Skip to content

Conversation

@radarhere
Copy link
Member

@radarhere radarhere commented Jul 27, 2024

Some improvements to ImageDraw2.

  1. You might think that ImageDraw2 ellipse() only requires xy,

def ellipse(self, xy: Coords, *options) -> None:

but that is not the case.

from PIL import Image, ImageDraw2
im = Image.new("RGB", (100, 100))
d = ImageDraw2.Draw(im)
d.ellipse((0, 0, 100, 100))

gives

Traceback (most recent call last):
  File "demo.py", line 4, in <module>
    d.ellipse((0, 0, 100, 100))
  File "PIL/ImageDraw2.py", line 138, in ellipse
    self.render("ellipse", xy, *options)
TypeError: render() missing 1 required positional argument: 'pen'

So I've made a change to add pen as a required argument to arc() and other methods.

Some of our test code does pass through pen as None, and uses the brush argument for the Pen instead.

pen = None
brush = ImageDraw2.Pen("yellow", width=2)
# Act
# Pass in the pen as the brush parameter
draw.line(points, pen, brush)

But even if pen is None, the fact that brush needs to come afterwards means that a value for pen is still required.

  1. At the moment, ImageDraw2 arc() does not work.

def arc(self, xy: Coords, start, end, *options) -> None:

>>> from PIL import Image, ImageDraw2
>>> im = Image.new("RGB", (1, 1))
>>> d = ImageDraw2.Draw(im)
>>> d.arc((0, 0), 0, 180)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/PIL/ImageDraw2.py", line 121, in arc
    self.render("arc", xy, start, end, *options)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/PIL/ImageDraw2.py", line 107, in render
    getattr(self.draw, op)(xy, fill=fill, outline=outline)
TypeError: arc() got an unexpected keyword argument 'outline'

This is because ImageDraw2 render() passes outline to every method except for line(), but ImageDraw arc() doesn't accept that.

if op == "line":
self.draw.line(xy, fill=outline, width=width)
else:
getattr(self.draw, op)(xy, fill=fill, outline=outline)

Pillow/src/PIL/ImageDraw.py

Lines 174 to 181 in 8f62fbd

def arc(
self,
xy: Coords,
start: float,
end: float,
fill: _Ink | None = None,
width: int = 1,
) -> None:

I've made a change for that.

  1. You will also notice in the above code that the required start and end parameters aren't passed through to ImageDraw. I've added **kwargs to render() to allow them to be added.

@hugovk
Copy link
Member

hugovk commented Aug 1, 2024

Thanks, this makes the API easier to use 👍

@hugovk hugovk merged commit 126af36 into python-pillow:main Aug 1, 2024
@radarhere radarhere deleted the imagedraw2 branch August 1, 2024 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants