将 png 粘贴到另一个 png 上而不覆盖背景图像(枕头)

Pasting a png on to another png without covering up the background image (pillow)

正如建议的名称,我想将一个 png 粘贴到另一个 png 上。但是,当我尝试这样做时,有点像 PIL 将 alpha 通道占用的像素更改为透明。

这里有一个例子可以说明我的意思。

首先我制作了一个实心的绿色块并将其保存为 png

im = Image.new("RGBA", (500,500),(,150,0,255))
im.save(r".\test.png")

图像是这样的:

接下来我制作第二张较小的完全透明图像并将其粘贴到保存的图像上。

im2 = Image.new("RGBA", (100,100), (0,0,0,0))
im3 = Image.open(r".\test.png")
im3.paste(im2,(0,0))
im3.save(r".\test.png")

结果如下:

我想要的是最后一张图片看起来像第一张图片。把透明方块贴上去后

正如@jasonharper 评论的那样,

.paste() uses a separate mask image to specify where to change pixels. You want .alpha_composite() to use the image's own alpha channel as the mask.

执行相同操作的函数如下:

from PIL import Image


def func(bg: Image.Image, fg: Image.Image, coordinates: tuple[int, int] = (0, 0)) -> Image.Image:
    """Paster ``fg`` on ``bg`` using its alpha channel

    Args:
        bg (Image.Image): the background image.
        fg (Image.Image): the foreground image.
        coordinates (tuple[int,int], optional): the coordinates at which ``fg`` need to be pasted. Defaults to (0,0).

    Returns:
        Image.Image: the final image
    """
    bg.paste(fg, coordinates, fg)
    return bg

您可以通过以下方式复制您的示例: 您可以了解更多关于它们的信息:paste() and alpha_composite().

(PS: 这是我在 Whosebug 上的第一个回答)