1
from __future__ import annotations
7
from PIL import Image, ImageDraw, ImageDraw2, features
8
from PIL._typing import Coords
12
assert_image_equal_tofile,
13
assert_image_similar_tofile,
19
WHITE = (255, 255, 255)
22
IMAGES_PATH = os.path.join("Tests", "images", "imagedraw")
34
BBOX = (((X0, Y0), (X1, Y1)), [(X0, Y0), (X1, Y1)], (X0, Y0, X1, Y1), [X0, Y0, X1, Y1])
38
((10, 10), (20, 40), (30, 30)),
39
[(10, 10), (20, 40), (30, 30)],
40
(10, 10, 20, 40, 30, 30),
41
[10, 10, 20, 40, 30, 30],
44
FONT_PATH = "Tests/fonts/FreeMono.ttf"
47
def test_sanity() -> None:
48
im = hopper("RGB").copy()
50
draw = ImageDraw2.Draw(im)
51
pen = ImageDraw2.Pen("blue", width=7)
52
draw.line(list(range(10)), pen)
54
draw2, handler = ImageDraw.getdraw(im)
55
assert draw2 is not None
56
pen = ImageDraw2.Pen("blue", width=7)
57
draw2.line(list(range(10)), pen)
60
def test_mode() -> None:
61
draw = ImageDraw2.Draw("L", (1, 1))
62
assert draw.image.mode == "L"
64
with pytest.raises(ValueError):
68
@pytest.mark.parametrize("bbox", BBOX)
69
@pytest.mark.parametrize("start, end", ((0, 180), (0.5, 180.4)))
70
def test_arc(bbox: Coords, start: float, end: float) -> None:
72
im = Image.new("RGB", (W, H))
73
draw = ImageDraw2.Draw(im)
74
pen = ImageDraw2.Pen("white", width=1)
77
draw.arc(bbox, pen, start, end)
80
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc.png", 1)
83
@pytest.mark.parametrize("bbox", BBOX)
84
def test_chord(bbox: Coords) -> None:
86
im = Image.new("RGB", (W, H))
87
draw = ImageDraw2.Draw(im)
88
pen = ImageDraw2.Pen("yellow")
89
brush = ImageDraw2.Brush("red")
92
draw.chord(bbox, pen, 0, 180, brush)
95
assert_image_similar_tofile(im, "Tests/images/imagedraw_chord_RGB.png", 1)
98
@pytest.mark.parametrize("bbox", BBOX)
99
def test_ellipse(bbox: Coords) -> None:
101
im = Image.new("RGB", (W, H))
102
draw = ImageDraw2.Draw(im)
103
pen = ImageDraw2.Pen("blue", width=2)
104
brush = ImageDraw2.Brush("green")
107
draw.ellipse(bbox, pen, brush)
110
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_RGB.png", 1)
113
def test_ellipse_edge() -> None:
115
im = Image.new("RGB", (W, H))
116
draw = ImageDraw2.Draw(im)
117
brush = ImageDraw2.Brush("white")
120
draw.ellipse(((0, 0), (W - 1, H - 1)), brush)
123
assert_image_similar_tofile(im, "Tests/images/imagedraw_ellipse_edge.png", 1)
126
@pytest.mark.parametrize("points", POINTS)
127
def test_line(points: Coords) -> None:
129
im = Image.new("RGB", (W, H))
130
draw = ImageDraw2.Draw(im)
131
pen = ImageDraw2.Pen("yellow", width=2)
134
draw.line(points, pen)
137
assert_image_equal_tofile(im, "Tests/images/imagedraw_line.png")
140
@pytest.mark.parametrize("points", POINTS)
141
def test_line_pen_as_brush(points: Coords) -> None:
143
im = Image.new("RGB", (W, H))
144
draw = ImageDraw2.Draw(im)
146
brush = ImageDraw2.Pen("yellow", width=2)
150
draw.line(points, pen, brush)
153
assert_image_equal_tofile(im, "Tests/images/imagedraw_line.png")
156
@pytest.mark.parametrize("bbox", BBOX)
157
@pytest.mark.parametrize("start, end", ((-92, 46), (-92.2, 46.2)))
158
def test_pieslice(bbox: Coords, start: float, end: float) -> None:
160
im = Image.new("RGB", (W, H))
161
draw = ImageDraw2.Draw(im)
162
pen = ImageDraw2.Pen("blue")
163
brush = ImageDraw2.Brush("white")
166
draw.pieslice(bbox, pen, start, end, brush)
169
assert_image_similar_tofile(im, "Tests/images/imagedraw_pieslice.png", 1)
172
@pytest.mark.parametrize("points", POINTS)
173
def test_polygon(points: Coords) -> None:
175
im = Image.new("RGB", (W, H))
176
draw = ImageDraw2.Draw(im)
177
pen = ImageDraw2.Pen("blue", width=2)
178
brush = ImageDraw2.Brush("red")
181
draw.polygon(points, pen, brush)
184
assert_image_equal_tofile(im, "Tests/images/imagedraw_polygon.png")
187
@pytest.mark.parametrize("bbox", BBOX)
188
def test_rectangle(bbox: Coords) -> None:
190
im = Image.new("RGB", (W, H))
191
draw = ImageDraw2.Draw(im)
192
pen = ImageDraw2.Pen("green", width=2)
193
brush = ImageDraw2.Brush("black")
196
draw.rectangle(bbox, pen, brush)
199
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle.png")
202
def test_big_rectangle() -> None:
205
im = Image.new("RGB", (W, H))
206
bbox = [(-1, -1), (W + 1, H + 1)]
207
brush = ImageDraw2.Brush("orange")
208
draw = ImageDraw2.Draw(im)
209
expected = "Tests/images/imagedraw_big_rectangle.png"
212
draw.rectangle(bbox, brush)
215
assert_image_similar_tofile(im, expected, 1)
218
@skip_unless_feature("freetype2")
219
def test_text() -> None:
221
im = Image.new("RGB", (W, H))
222
draw = ImageDraw2.Draw(im)
223
font = ImageDraw2.Font("white", FONT_PATH)
224
expected = "Tests/images/imagedraw2_text.png"
227
draw.text((5, 5), "ImageDraw2", font)
230
assert_image_similar_tofile(im, expected, 13)
233
@skip_unless_feature("freetype2")
234
def test_textbbox() -> None:
236
im = Image.new("RGB", (W, H))
237
draw = ImageDraw2.Draw(im)
238
font = ImageDraw2.Font("white", FONT_PATH)
241
bbox = draw.textbbox((0, 0), "ImageDraw2", font)
244
right = 72 if features.check_feature("raqm") else 70
245
assert bbox == (0, 2, right, 12)
248
@skip_unless_feature("freetype2")
249
def test_textsize_empty_string() -> None:
251
im = Image.new("RGB", (W, H))
252
draw = ImageDraw2.Draw(im)
253
font = ImageDraw2.Font("white", FONT_PATH)
258
draw.textbbox((0, 0), "", font)
259
draw.textbbox((0, 0), "\n", font)
260
draw.textbbox((0, 0), "test\n", font)
261
draw.textlength("", font)
264
@skip_unless_feature("freetype2")
265
def test_flush() -> None:
267
im = Image.new("RGB", (W, H))
268
draw = ImageDraw2.Draw(im)
269
font = ImageDraw2.Font("white", FONT_PATH)
272
draw.text((5, 5), "ImageDraw2", font)
276
assert_image_equal(im, im2)