Skip to content

Commit 604e58f

Browse files
committed
Added width argument to polygon
1 parent d6e42f3 commit 604e58f

File tree

7 files changed

+51
-9
lines changed

7 files changed

+51
-9
lines changed
472 Bytes
Loading
Loading

Tests/test_imagedraw.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,18 @@ def test_triangle_right():
945945
)
946946

947947

948+
@pytest.mark.parametrize(
949+
"fill, suffix",
950+
((BLACK, "width"), (None, "width_no_fill")),
951+
)
952+
def test_triangle_right_width(fill, suffix):
953+
img, draw = create_base_image_draw((100, 100))
954+
draw.polygon([(15, 25), (85, 25), (50, 60)], fill, WHITE, width=5)
955+
assert_image_equal_tofile(
956+
img, os.path.join(IMAGES_PATH, "triangle_right_" + suffix + ".png")
957+
)
958+
959+
948960
def test_line_horizontal():
949961
img, draw = create_base_image_draw((20, 20))
950962
draw.line((5, 5, 14, 5), BLACK, 2)

src/PIL/ImageDraw.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,35 @@ def point(self, xy, fill=None):
233233
if ink is not None:
234234
self.draw.draw_points(xy, ink)
235235

236-
def polygon(self, xy, fill=None, outline=None):
236+
def polygon(self, xy, fill=None, outline=None, width=1):
237237
"""Draw a polygon."""
238238
ink, fill = self._getink(outline, fill)
239239
if fill is not None:
240240
self.draw.draw_polygon(xy, fill, 1)
241241
if ink is not None and ink != fill:
242-
self.draw.draw_polygon(xy, ink, 0)
242+
if width == 1:
243+
self.draw.draw_polygon(xy, ink, 0, width)
244+
else:
245+
# To avoid expanding the polygon outwards,
246+
# use the fill as a mask
247+
mask = Image.new("1", self.im.size)
248+
mask_ink = self._getink(1)[0]
249+
250+
fill_im = mask.copy()
251+
draw = Draw(fill_im)
252+
draw.draw.draw_polygon(xy, mask_ink, 1)
253+
254+
ink_im = mask.copy()
255+
draw = Draw(ink_im)
256+
width = width * 2 - 1
257+
draw.draw.draw_polygon(xy, mask_ink, 0, width)
258+
259+
mask.paste(ink_im, mask=fill_im)
260+
261+
im = Image.new(self.mode, self.im.size)
262+
draw = Draw(im)
263+
draw.draw.draw_polygon(xy, ink, 0, width)
264+
self.im.paste(im.im, (0, 0) + im.size, mask.im)
243265

244266
def regular_polygon(
245267
self, bounding_circle, n_sides, rotation=0, fill=None, outline=None

src/_imaging.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,7 +3124,8 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
31243124
PyObject *data;
31253125
int ink;
31263126
int fill = 0;
3127-
if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) {
3127+
int width = 0;
3128+
if (!PyArg_ParseTuple(args, "Oi|ii", &data, &ink, &fill, &width)) {
31283129
return NULL;
31293130
}
31303131

@@ -3153,7 +3154,7 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
31533154

31543155
free(xy);
31553156

3156-
if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, self->blend) < 0) {
3157+
if (ImagingDrawPolygon(self->image->image, n, ixy, &ink, fill, width, self->blend) < 0) {
31573158
free(ixy);
31583159
return NULL;
31593160
}

src/libImaging/Draw.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ ImagingDrawRectangle(
742742
}
743743

744744
int
745-
ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int op) {
745+
ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, int width, int op) {
746746
int i, n, x0, y0, x1, y1;
747747
DRAW *draw;
748748
INT32 ink;
@@ -790,10 +790,17 @@ ImagingDrawPolygon(Imaging im, int count, int *xy, const void *ink_, int fill, i
790790

791791
} else {
792792
/* Outline */
793-
for (i = 0; i < count - 1; i++) {
794-
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink);
793+
if (width == 1) {
794+
for (i = 0; i < count - 1; i++) {
795+
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink);
796+
}
797+
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
798+
} else {
799+
for (i = 0; i < count - 1; i++) {
800+
ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[i * 2 + 2], xy[i * 2 + 3], ink_, width, op);
801+
}
802+
ImagingDrawWideLine(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink_, width, op);
795803
}
796-
draw->line(im, xy[i * 2], xy[i * 2 + 1], xy[0], xy[1], ink);
797804
}
798805

799806
return 0;

src/libImaging/Imaging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ ImagingDrawPieslice(
487487
extern int
488488
ImagingDrawPoint(Imaging im, int x, int y, const void *ink, int op);
489489
extern int
490-
ImagingDrawPolygon(Imaging im, int points, int *xy, const void *ink, int fill, int op);
490+
ImagingDrawPolygon(Imaging im, int points, int *xy, const void *ink, int fill, int width, int op);
491491
extern int
492492
ImagingDrawRectangle(
493493
Imaging im,

0 commit comments

Comments
 (0)