python-pillow / Pillow

Python Imaging Library (Fork)
https://python-pillow.org
Other
12.35k stars 2.24k forks source link

Improve ImageDraw2 shape methods #8265

Closed radarhere closed 4 months ago

radarhere commented 4 months ago

Some improvements to ImageDraw2.

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

https://github.com/python-pillow/Pillow/blob/8f62fbdf440b99cc087c19b58725ff266b76758d/src/PIL/ImageDraw2.py#L132

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.

https://github.com/python-pillow/Pillow/blob/8f62fbdf440b99cc087c19b58725ff266b76758d/Tests/test_imagedraw2.py#L115-L120

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.

https://github.com/python-pillow/Pillow/blob/8f62fbdf440b99cc087c19b58725ff266b76758d/src/PIL/ImageDraw2.py#L114

>>> 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.

https://github.com/python-pillow/Pillow/blob/8f62fbdf440b99cc087c19b58725ff266b76758d/src/PIL/ImageDraw2.py#L104-L107

https://github.com/python-pillow/Pillow/blob/8f62fbdf440b99cc087c19b58725ff266b76758d/src/PIL/ImageDraw.py#L174-L181

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 commented 4 months ago

Thanks, this makes the API easier to use 👍