Added width argument to polygon

This commit is contained in:
Andrew Murray 2021-11-16 22:02:54 +11:00
parent d6e42f3307
commit 90a52d3c0d
7 changed files with 52 additions and 10 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

View File

@ -945,6 +945,18 @@ def test_triangle_right():
)
@pytest.mark.parametrize(
"fill, suffix",
((BLACK, "width"), (None, "width_no_fill")),
)
def test_triangle_right_width(fill, suffix):
img, draw = create_base_image_draw((100, 100))
draw.polygon([(15, 25), (85, 25), (50, 60)], fill, WHITE, width=5)
assert_image_equal_tofile(
img, os.path.join(IMAGES_PATH, "triangle_right_" + suffix + ".png")
)
def test_line_horizontal():
img, draw = create_base_image_draw((20, 20))
draw.line((5, 5, 14, 5), BLACK, 2)

View File

@ -233,13 +233,35 @@ class ImageDraw:
if ink is not None:
self.draw.draw_points(xy, ink)
def polygon(self, xy, fill=None, outline=None):
def polygon(self, xy, fill=None, outline=None, width=1):
"""Draw a polygon."""
ink, fill = self._getink(outline, fill)
if fill is not None:
self.draw.draw_polygon(xy, fill, 1)
if ink is not None and ink != fill:
self.draw.draw_polygon(xy, ink, 0)
if ink is not None and ink != fill and width != 0:
if width == 1:
self.draw.draw_polygon(xy, ink, 0, width)
else:
# 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)
def regular_polygon(
self, bounding_circle, n_sides, rotation=0, fill=None, outline=None

View File

@ -3124,7 +3124,8 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
PyObject *data;
int ink;
int fill = 0;
if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) {
int width = 0;
if (!PyArg_ParseTuple(args, "Oi|ii", &data, &ink, &fill, &width)) {
return NULL;
}
@ -3153,7 +3154,7 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
free(xy);
if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, self->blend) < 0) {
if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, width, self->blend) < 0) {
free(ixy);
return NULL;
}

View File

@ -742,7 +742,7 @@ ImagingDrawRectangle(
}
int
ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int op) {
ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int width, int op) {
int i, n, x0, y0, x1, y1;
DRAW *draw;
INT32 ink;
@ -790,10 +790,17 @@ ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, i
} else {
/* Outline */
for (i = 0; i < count - 1; i++) {
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink);
if (width == 1) {
for (i = 0; i < count - 1; i++) {
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink);
}
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
} else {
for (i = 0; i < count - 1; i++) {
ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink_, width, op);
}
ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink_, width, op);
}
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
}
return 0;

View File

@ -487,7 +487,7 @@ ImagingDrawPieslice(
extern int
ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op);
extern int
ImagingDrawPolygon(Imaging im, int points, int *xy, const void *ink, int fill, int op);
ImagingDrawPolygon(Imaging im, int points, int *xy, const void *ink, int fill, int width, int op);
extern int
ImagingDrawRectangle(
Imaging im,