Как создать перекрывающиеся полупрозрачные фигуры на полупрозрачном фоне с помощью PIL - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь создать изображение с полупрозрачными фигурами, нарисованными на прозрачном фоне.По какой-то причине вместо того, чтобы оставаться прозрачным, фигуры полностью покрывают те, что находятся под ними.Мой код:

from PIL import Image, ImageDraw
img = Image.new("RGBA", (256, 256), (255,0,0,127))
drawing = ImageDraw.Draw(img, "RGBA")
drawing.ellipse((127-79, 127 - 63, 127 + 47, 127 + 63), fill=(0, 255, 0, 63), outline=(0, 255, 0, 255))
drawing.ellipse((127-47, 127 - 63, 127 + 79, 127 + 63), fill=(0, 0, 255, 63), outline=(0, 0, 255, 255))
img.save("foo.png", "png")

Я ожидаю, что результат будет выглядеть примерно так (за исключением непрозрачного фона):
expected
, но выглядит так:
actual

Когда я пытаюсь сохранить его как GIF с img.save("foo.gif", "gif"), результат еще хуже.Круги сплошные, нет разницы между контуром и заливкой.

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Как я уже упоминал в комментарии, 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

0 голосов
/ 29 января 2019

Все 4-й размер прозрачности должен быть наполовину.Также возможно проблема с рисунком.Сделайте маску для каждого эллипса, а затем суммируйте изображения.Последний вариант - проверьте функцию pil на наличие изгибаемых изображений.Вероятно, это будет наиболее верное и простое решение.

Функция смешивания:

PIL.Image. blend (im1, im2, alpha)
...