Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve ImageDraw2 shape methods #8265

Merged
merged 3 commits into from
Aug 1, 2024
Merged

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
53 checks passed
@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