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

Incorrect border color in corners when drawing rectangles with border color with opacity < 1 #5182

Closed
macjohnny opened this issue Jan 5, 2021 · 3 comments · Fixed by #5183

Comments

@macjohnny
Copy link
Contributor

macjohnny commented Jan 5, 2021

What did you do?

Draw a rectangle with a color with opacity < 1 for border (e.g. outline='#0000ffaa')

What did you expect to happen?

The border color should be homogenous, and not altered by the fill color, if set.

What actually happened?

image
The border color is different in the corners, probably due to overlapping line segments.
Moreover, when a fill color is set, the border color is changed due to the overlap of the border and fill rectangle.

What are your OS, Python and Pillow versions?

  • OS: Windows 10
  • Python: 3.8
  • Pillow: 8.0.1

Example

Code

import PIL.Image
import PIL.ImageDraw

image = PIL.Image.new(mode='RGB', size=(500, 500), color='#ffffff')
draw = PIL.ImageDraw.ImageDraw(image, mode='RGBA')
draw.rectangle(xy=((100,100), (200,200)),
               fill='#ffff00',
               outline='#0000ffaa',
               width=10)
draw.rectangle(xy=((205,100), (305,200)),
               outline='#0000ffaa',
               width=10)

image.save('image.png')

Result

image

Related Sources

Pillow/src/PIL/ImageDraw.py

Lines 255 to 258 in d374015

if fill is not None:
self.draw.draw_rectangle(xy, fill, 1)
if ink is not None and ink != fill and width != 0:
self.draw.draw_rectangle(xy, ink, 0, width)

Pillow/src/_imaging.c

Lines 3171 to 3180 in d374015

n = ImagingDrawRectangle(
self->image->image,
(int)xy[0],
(int)xy[1],
(int)xy[2],
(int)xy[3],
&ink,
fill,
width,
self->blend);

for (i = 0; i < width; i++) {
draw->hline(im, x0, y0 + i, x1, ink);
draw->hline(im, x0, y1 - i, x1, ink);
draw->line(im, x1 - i, y0, x1 - i, y1, ink);
draw->line(im, x0 + i, y1, x0 + i, y0, ink);
}

@radarhere radarhere changed the title incorrect border color in corners when drawing rectangles with border color with opacity < 1 Incorrect border color in corners when drawing rectangles with border color with opacity < 1 Jan 5, 2021
@radarhere
Copy link
Member

I've created PR #5183 to fix the corners.

For my part at least, I'm not convinced that a translucent outline shouldn't be drawn on top of the fill color? Seems like that decision could go either way.

@macjohnny
Copy link
Contributor Author

I've created PR #5183 to fix the corners.

thanks for the quick fix, looks good.

For my part at least, I'm not convinced that a translucent outline shouldn't be drawn on top of the fill color? Seems like that decision could go either way.

the rectangle drawing option in e.g. Skia (https://api.skia.org/classSkCanvas.html#a15a77a3479b8f8731442d4a4ea2772b3) uses the same color for stroke and fill.
the web apis offer two different functions:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeRect
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillRect

so I guess it is ok to combine two rectangles if we want to have a translucent outline not overlapping with the fill rectangle.

@radarhere
Copy link
Member

Thanks. I think it is best to leave the translucent outline drawing on top of the fill then, for the sake of backwards compatibility.

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 a pull request may close this issue.

2 participants