Use mask in C when drawing wide polygon lines by radarhere · Pull Request #8984 · python-pillow/Pillow
Resolves #8976
If we just drew thicker lines when creating a polygon, then since the centre of the line is the edge, half of each line would be drawn outside the filled polygon. To avoid this, #5694 introduced masking using the Python API.
| if width == 1: | |
| self.draw.draw_polygon(xy, ink, 0, width) | |
| elif self.im is not None: | |
| # To avoid expanding the polygon outwards, | |
| # use the fill as a mask | |
| mask = Image.new("1", self.im.size) | |
| mask_ink = self._getink(1)[0] | |
| fill_im = mask.copy() | |
| draw = Draw(fill_im) | |
| draw.draw.draw_polygon(xy, mask_ink, 1) | |
| ink_im = mask.copy() | |
| draw = Draw(ink_im) | |
| width = width * 2 - 1 | |
| draw.draw.draw_polygon(xy, mask_ink, 0, width) | |
| mask.paste(ink_im, mask=fill_im) | |
| im = Image.new(self.mode, self.im.size) | |
| draw = Draw(im) | |
| draw.draw.draw_polygon(xy, ink, 0, width) | |
| self.im.paste(im.im, (0, 0) + im.size, mask.im) |
However, #8976 finds this to be slow. So instead of
- drawing a filled polygon
- drawing the outline
- combining those two to create a mask of just the outline inside the polygon
- drawing the outline again, and pasting it onto the final image with that mask
this PR
- draws a filled polygon
- draws the outline onto the final image, passing the filled polygon as a mask into the C layer. Every time a pixel is to be 'drawn', the mask image is checked to see whether or not to do so.
The first two commits simplify the existing code by removing polygon from the DRAW struct.
| typedef struct { | |
| void (*point)(Imaging im, int x, int y, int ink); | |
| void (*hline)(Imaging im, int x0, int y0, int x1, int ink); | |
| void (*line)(Imaging im, int x0, int y0, int x1, int y1, int ink); | |
| int (*polygon)(Imaging im, int n, Edge *e, int ink, int eofill); | |
| } DRAW; |
This just means that polygon_generic can be used more directly, and the mask doesn't need to be passed through each different type of polygon function.