Как я уже упоминал в комментарии, ImageDraw.Draw
не выполняет смешивание - все, что нарисовано, заменяет любые пиксели, которые были там ранее.Чтобы получить желаемый эффект, нужно рисовать вещи в два этапа.Эллипс должен сначала быть нарисован на чистом прозрачном фоне, а затем он должен быть альфа-композитный с текущим изображением (bg_img
), чтобы сохранить прозрачность.
В коде ниже это aбыла реализована в многократно используемой функции:
from PIL import Image, ImageDraw
def draw_transp_ellipse(img, xy, **kwargs):
""" Draws an ellipse inside the given bounding box onto given image.
Supports transparent colors
"""
transp = Image.new('RGBA', img.size, (0,0,0,0)) # Temp drawing image.
draw = ImageDraw.Draw(transp, "RGBA")
draw.ellipse(xy, **kwargs)
# Alpha composite two images together and replace first with result.
img.paste(Image.alpha_composite(img, transp))
bg_img = Image.new("RGBA", (256, 256), (255, 0, 0, 127)) # Semitransparent background.
draw_transp_ellipse(bg_img, (127-79, 127-63, 127+47, 127+63),
fill=(0, 255, 0, 63), outline=(0, 255, 0, 255))
draw_transp_ellipse(bg_img, (127-47, 127-63, 127+79, 127+63),
fill=(0, 0, 255, 63), outline=(0, 0, 255, 255))
bg_img.save("foo.png")
Это изображение, которое оно создало, просмотренное в моем приложении редактора файлов изображений, которое отображает полупрозрачные части изображений с рисунком в виде шахматной доски.Как вы можете видеть, непрозрачные контуры являются единственной частью, которая не является.
![screenshot of image in image editor](https://i.stack.imgur.com/FgILs.png)