Skip to content
Advertisement

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

As the name of the suggests I want to paste a png onto another png. However when I try to do this it’s kinda like PIL changes the pixels occupied by the alpha channel to to be transparent.

Here’s an example to show you what I mean.

First I make a solid green block and save it as a png

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

The image look like this:

enter image description here

Next I make a second, smaller, fully transparent image and paste that on the saved image.

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")

Here is the result:

enter image description here

What I want is for that last image to look like the first one. After pasting the transparent block onto it.

Advertisement

Answer

as commented by @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.

A function that does the same is as follows:

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

You can replicate your example by : you can learn more about them: paste() and alpha_composite().

(PS: this is my first answer on stackoverflow)

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement