Merge pull request #8265 from radarhere/imagedraw2

This commit is contained in:
Hugo van Kemenade 2024-08-01 14:50:43 +03:00 committed by GitHub
commit 126af363af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 94 additions and 18 deletions

View File

@ -65,6 +65,36 @@ def test_mode() -> None:
ImageDraw2.Draw("L")
@pytest.mark.parametrize("bbox", BBOX)
@pytest.mark.parametrize("start, end", ((0, 180), (0.5, 180.4)))
def test_arc(bbox: Coords, start: float, end: float) -> None:
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw2.Draw(im)
pen = ImageDraw2.Pen("white", width=1)
# Act
draw.arc(bbox, pen, start, end)
# Assert
assert_image_similar_tofile(im, "Tests/images/imagedraw_arc.png", 1)
@pytest.mark.parametrize("bbox", BBOX)
def test_chord(bbox: Coords) -> None:
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw2.Draw(im)
pen = ImageDraw2.Pen("yellow")
brush = ImageDraw2.Brush("red")
# Act
draw.chord(bbox, pen, 0, 180, brush)
# Assert
assert_image_similar_tofile(im, "Tests/images/imagedraw_chord_RGB.png", 1)
@pytest.mark.parametrize("bbox", BBOX)
def test_ellipse(bbox: Coords) -> None:
# Arrange
@ -123,6 +153,22 @@ def test_line_pen_as_brush(points: Coords) -> None:
assert_image_equal_tofile(im, "Tests/images/imagedraw_line.png")
@pytest.mark.parametrize("bbox", BBOX)
@pytest.mark.parametrize("start, end", ((-92, 46), (-92.2, 46.2)))
def test_pieslice(bbox: Coords, start: float, end: float) -> None:
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw2.Draw(im)
pen = ImageDraw2.Pen("blue")
brush = ImageDraw2.Brush("white")
# Act
draw.pieslice(bbox, pen, start, end, brush)
# Assert
assert_image_similar_tofile(im, "Tests/images/imagedraw_pieslice.png", 1)
@pytest.mark.parametrize("points", POINTS)
def test_polygon(points: Coords) -> None:
# Arrange

View File

@ -80,7 +80,12 @@ class Draw:
return self.image
def render(
self, op: str, xy: Coords, pen: Pen | Brush, brush: Brush | Pen | None = None
self,
op: str,
xy: Coords,
pen: Pen | Brush | None,
brush: Brush | Pen | None = None,
**kwargs: Any,
) -> None:
# handle color arguments
outline = fill = None
@ -101,60 +106,85 @@ class Draw:
path.transform(self.transform)
xy = path
# render the item
if op == "line":
self.draw.line(xy, fill=outline, width=width)
if op in ("arc", "line"):
kwargs.setdefault("fill", outline)
else:
getattr(self.draw, op)(xy, fill=fill, outline=outline)
kwargs.setdefault("fill", fill)
kwargs.setdefault("outline", outline)
if op == "line":
kwargs.setdefault("width", width)
getattr(self.draw, op)(xy, **kwargs)
def settransform(self, offset: tuple[float, float]) -> None:
"""Sets a transformation offset."""
(xoffset, yoffset) = offset
self.transform = (1, 0, xoffset, 0, 1, yoffset)
def arc(self, xy: Coords, start, end, *options: Any) -> None:
def arc(
self,
xy: Coords,
pen: Pen | Brush | None,
start: float,
end: float,
*options: Any,
) -> None:
"""
Draws an arc (a portion of a circle outline) between the start and end
angles, inside the given bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.arc`
"""
self.render("arc", xy, start, end, *options)
self.render("arc", xy, pen, *options, start=start, end=end)
def chord(self, xy: Coords, start, end, *options: Any) -> None:
def chord(
self,
xy: Coords,
pen: Pen | Brush | None,
start: float,
end: float,
*options: Any,
) -> None:
"""
Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points
with a straight line.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord`
"""
self.render("chord", xy, start, end, *options)
self.render("chord", xy, pen, *options, start=start, end=end)
def ellipse(self, xy: Coords, *options: Any) -> None:
def ellipse(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None:
"""
Draws an ellipse inside the given bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.ellipse`
"""
self.render("ellipse", xy, *options)
self.render("ellipse", xy, pen, *options)
def line(self, xy: Coords, *options: Any) -> None:
def line(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None:
"""
Draws a line between the coordinates in the ``xy`` list.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.line`
"""
self.render("line", xy, *options)
self.render("line", xy, pen, *options)
def pieslice(self, xy: Coords, start, end, *options: Any) -> None:
def pieslice(
self,
xy: Coords,
pen: Pen | Brush | None,
start: float,
end: float,
*options: Any,
) -> None:
"""
Same as arc, but also draws straight lines between the end points and the
center of the bounding box.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.pieslice`
"""
self.render("pieslice", xy, start, end, *options)
self.render("pieslice", xy, pen, *options, start=start, end=end)
def polygon(self, xy: Coords, *options: Any) -> None:
def polygon(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None:
"""
Draws a polygon.
@ -165,15 +195,15 @@ class Draw:
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.polygon`
"""
self.render("polygon", xy, *options)
self.render("polygon", xy, pen, *options)
def rectangle(self, xy: Coords, *options: Any) -> None:
def rectangle(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None:
"""
Draws a rectangle.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.rectangle`
"""
self.render("rectangle", xy, *options)
self.render("rectangle", xy, pen, *options)
def text(self, xy: tuple[float, float], text: AnyStr, font: Font) -> None:
"""