Reputation: 13
I am trying to draw multiple transparent ellipses with Pillow, and I want to draw them without outlines. I can't seem to make it work without outlines.
Here is some test code:
from PIL import Image, ImageDraw
w,h = 100,100
img = Image.new('RGB', (w,h),(255,255,255))
drw = ImageDraw.Draw(img,"RGBA")
drw.polygon([(50, 0), (100, 100), (0, 100)], (255, 0, 0, 125))
drw.polygon([(50,100), (100, 0), (0, 0)], (0, 255, 0, 125))
drw.ellipse([(40, 40), (w - 10, h - 10)], fill=(0,0,255,125), outline=None)
img.save('out.png', 'PNG')
(from here, with some modifications)
Only the ellipse gets an outline. Why? How can I avoid this?
Upvotes: 1
Views: 3179
Reputation: 18925
After playing around with some codes, looking at the documentation and some source codes, I'm quite sure, that most likely there's some issue with the functions like arc
, chord
, ellipse
, that all share the same code under the hood.
I created the following example:
from matplotlib import pyplot as plt
from PIL import Image, ImageDraw
def example(outline_alpha=None, width=None):
if outline_alpha is None:
outline = None
else:
outline = (255, 255, 0, outline_alpha)
if width is None:
width = 0
img = Image.new('RGB', (100, 100), (255, 255, 255))
drw = ImageDraw.Draw(img, 'RGBA')
drw.line([(0, 40), (100, 40)], (0, 0, 0, 255))
drw.line([(50, 100), (100, 0)], (0, 0, 0, 255))
drw.polygon([(50, 100), (100, 0), (0, 0)], (0, 255, 0, 128), outline)
drw.ellipse([(40, 40), (90, 90)], (0, 0, 255, 128), outline, width)
return img
plt.figure(1, figsize=(15, 10))
plt.subplot(2, 3, 1), plt.imshow(example()), plt.title('No outlines specified, width = 0')
plt.subplot(2, 3, 2), plt.imshow(example(255)), plt.title('Opaque outlines specified, width = 0')
plt.subplot(2, 3, 3), plt.imshow(example(128)), plt.title('Semi-transparent outlines specified, width = 0')
plt.subplot(2, 3, 4), plt.imshow(example(None, 5)), plt.title('No outlines specified, width = 5')
plt.subplot(2, 3, 5), plt.imshow(example(255, 5)), plt.title('Opaque outlines specified, width = 5')
plt.subplot(2, 3, 6), plt.imshow(example(20, 5)), plt.title('Semi-transparent outlines specified, width = 5')
plt.tight_layout()
plt.show()
The output is the following:
Looking at the polygon, if no outline is specified (top left image), we see that the black line is visible, which is one of the polygon's borders. Specifying an opaque outline (top center image), the black line's no longer visible. Setting a semi-transparent outline (top right image) reveals, that the outline is identical to the polygon's border.
Now, the same for the ellipse: If no outline is set (top left), an outline is shown nevertheless, most likely the same color as used for the fill
parameter, but without incorporating an alpha value. Setting an opaque outline (top center) "overwrites" the unexpected existent outline, but when setting a semi-transparent outline, we see that the unexpected outline is still there.
This effect becomes even more obvious, when setting width > 1
in ellipse
, see the bottom row. The unexpected outline still seems to have width = 1
, whereas the explicitly set outline has width = 5
.
Again, I'm quite sure, that this behavior isn't intended – and I will open an issue in their GitHub issue tracker. EDIT: I just opened this issue. ANOTHER EDIT: It's fixed.
Hope that helps – somehow...
Upvotes: 1