mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 18:56:17 +03:00
Only draw each pixel once
This commit is contained in:
parent
f5d49f4f61
commit
9ce3eba7eb
BIN
Tests/images/imagedraw_rounded_rectangle_both.png
Normal file
BIN
Tests/images/imagedraw_rounded_rectangle_both.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 530 B |
BIN
Tests/images/imagedraw_rounded_rectangle_x.png
Normal file
BIN
Tests/images/imagedraw_rounded_rectangle_x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 567 B |
BIN
Tests/images/imagedraw_rounded_rectangle_y.png
Normal file
BIN
Tests/images/imagedraw_rounded_rectangle_y.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 528 B |
|
@ -734,6 +734,30 @@ def test_rounded_rectangle_zero_radius():
|
||||||
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle_width_fill.png")
|
assert_image_equal_tofile(im, "Tests/images/imagedraw_rectangle_width_fill.png")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"xy, suffix",
|
||||||
|
[
|
||||||
|
((20, 10, 80, 90), "x"),
|
||||||
|
((10, 20, 90, 80), "y"),
|
||||||
|
((20, 20, 80, 80), "both"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_rounded_rectangle_translucent(xy, suffix):
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (W, H))
|
||||||
|
draw = ImageDraw.Draw(im, "RGBA")
|
||||||
|
|
||||||
|
# Act
|
||||||
|
draw.rounded_rectangle(
|
||||||
|
xy, 30, fill=(255, 0, 0, 127), outline=(0, 255, 0, 127), width=5
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert_image_equal_tofile(
|
||||||
|
im, "Tests/images/imagedraw_rounded_rectangle_" + suffix + ".png"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_floodfill():
|
def test_floodfill():
|
||||||
red = ImageColor.getrgb("red")
|
red = ImageColor.getrgb("red")
|
||||||
|
|
||||||
|
|
|
@ -264,19 +264,65 @@ class ImageDraw:
|
||||||
else:
|
else:
|
||||||
x0, y0, x1, y1 = xy
|
x0, y0, x1, y1 = xy
|
||||||
|
|
||||||
# Do not allow the diameter to be greater than the width or height
|
d = radius * 2
|
||||||
d = min(radius * 2, x1 - x0, y1 - y0)
|
|
||||||
|
full_x = d >= x1 - x0
|
||||||
|
if full_x:
|
||||||
|
# The two left and two right corners are joined
|
||||||
|
d = x1 - x0
|
||||||
|
full_y = d >= y1 - y0
|
||||||
|
if full_y:
|
||||||
|
# The two top and two bottom corners are joined
|
||||||
|
d = y1 - y0
|
||||||
|
if full_x and full_y:
|
||||||
|
# If all corners are joined, that is a circle
|
||||||
|
return self.ellipse(xy, fill, outline, width)
|
||||||
|
|
||||||
if d == 0:
|
if d == 0:
|
||||||
|
# If the corners have no curve, that is a rectangle
|
||||||
return self.rectangle(xy, fill, outline, width)
|
return self.rectangle(xy, fill, outline, width)
|
||||||
|
|
||||||
ink, fill = self._getink(outline, fill)
|
ink, fill = self._getink(outline, fill)
|
||||||
if fill is not None:
|
|
||||||
self.draw.draw_pieslice((x1 - d, y0, x1, y0 + d), 270, 360, fill, 1)
|
|
||||||
self.draw.draw_pieslice((x1 - d, y1 - d, x1, y1), 0, 90, fill, 1)
|
|
||||||
self.draw.draw_pieslice((x0, y1 - d, x0 + d, y1), 90, 180, fill, 1)
|
|
||||||
self.draw.draw_pieslice((x0, y0, x0 + d, y0 + d), 180, 270, fill, 1)
|
|
||||||
|
|
||||||
self.draw.draw_rectangle((x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y1), fill, 1)
|
def draw_corners(pieslice):
|
||||||
|
if full_x:
|
||||||
|
# Draw top and bottom halves
|
||||||
|
parts = (
|
||||||
|
((x0, y0, x0 + d, y0 + d), 180, 360),
|
||||||
|
((x0, y1 - d, x0 + d, y1), 0, 180),
|
||||||
|
)
|
||||||
|
elif full_y:
|
||||||
|
# Draw left and right halves
|
||||||
|
parts = (
|
||||||
|
((x0, y0, x0 + d, y0 + d), 90, 270),
|
||||||
|
((x1 - d, y0, x1, y0 + d), 270, 90),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Draw four separate corners
|
||||||
|
parts = (
|
||||||
|
((x1 - d, y0, x1, y0 + d), 270, 360),
|
||||||
|
((x1 - d, y1 - d, x1, y1), 0, 90),
|
||||||
|
((x0, y1 - d, x0 + d, y1), 90, 180),
|
||||||
|
((x0, y0, x0 + d, y0 + d), 180, 270),
|
||||||
|
)
|
||||||
|
for part in parts:
|
||||||
|
if pieslice:
|
||||||
|
self.draw.draw_pieslice(*(part + (fill, 1)))
|
||||||
|
else:
|
||||||
|
self.draw.draw_arc(*(part + (ink, width)))
|
||||||
|
|
||||||
|
if fill is not None:
|
||||||
|
draw_corners(True)
|
||||||
|
|
||||||
|
if full_x:
|
||||||
|
self.draw.draw_rectangle(
|
||||||
|
(x0, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.draw.draw_rectangle(
|
||||||
|
(x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y1), fill, 1
|
||||||
|
)
|
||||||
|
if not full_x and not full_y:
|
||||||
self.draw.draw_rectangle(
|
self.draw.draw_rectangle(
|
||||||
(x0, y0 + d / 2 + 1, x0 + d / 2, y1 - d / 2 - 1), fill, 1
|
(x0, y0 + d / 2 + 1, x0 + d / 2, y1 - d / 2 - 1), fill, 1
|
||||||
)
|
)
|
||||||
|
@ -284,22 +330,21 @@ class ImageDraw:
|
||||||
(x1 - d / 2, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1
|
(x1 - d / 2, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), fill, 1
|
||||||
)
|
)
|
||||||
if ink is not None and ink != fill and width != 0:
|
if ink is not None and ink != fill and width != 0:
|
||||||
self.draw.draw_arc((x1 - d, y0, x1, y0 + d), 270, 360, ink, width)
|
draw_corners(False)
|
||||||
self.draw.draw_arc((x1 - d, y1 - d, x1, y1), 0, 90, ink, width)
|
|
||||||
self.draw.draw_arc((x0, y1 - d, x0 + d, y1), 90, 180, ink, width)
|
|
||||||
self.draw.draw_arc((x0, y0, x0 + d, y0 + d), 180, 270, ink, width)
|
|
||||||
|
|
||||||
|
if not full_x:
|
||||||
self.draw.draw_rectangle(
|
self.draw.draw_rectangle(
|
||||||
(x1 - width + 1, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), ink, 1
|
(x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y0 + width - 1), ink, 1
|
||||||
)
|
)
|
||||||
self.draw.draw_rectangle(
|
self.draw.draw_rectangle(
|
||||||
(x0 + d / 2 + 1, y1 - width + 1, x1 - d / 2 - 1, y1), ink, 1
|
(x0 + d / 2 + 1, y1 - width + 1, x1 - d / 2 - 1, y1), ink, 1
|
||||||
)
|
)
|
||||||
|
if not full_y:
|
||||||
self.draw.draw_rectangle(
|
self.draw.draw_rectangle(
|
||||||
(x0, y0 + d / 2 + 1, x0 + width - 1, y1 - d / 2 - 1), ink, 1
|
(x0, y0 + d / 2 + 1, x0 + width - 1, y1 - d / 2 - 1), ink, 1
|
||||||
)
|
)
|
||||||
self.draw.draw_rectangle(
|
self.draw.draw_rectangle(
|
||||||
(x0 + d / 2 + 1, y0, x1 - d / 2 - 1, y0 + width - 1), ink, 1
|
(x1 - width + 1, y0 + d / 2 + 1, x1, y1 - d / 2 - 1), ink, 1
|
||||||
)
|
)
|
||||||
|
|
||||||
def _multiline_check(self, text):
|
def _multiline_check(self, text):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user