Search code examples
python-3.xpython-imaging-librarypnggif

Place GIF in front of a PNG with Python PIL library


I am trying to merge a PNG file with a GIF file using Python 3 and PIL library.

I want to place the PNG file in the background, and the GIF file in the foreground.I was able to do the opposite, placing a GIF file in the background and a PNG file in the foreground. Thanks to the person who answered here: How to merge a image and a Gif in Python Pillow However, when I try to do what I need, I get only the transparent GIF and no PNG on the background of the image.

I use this transparent GIF: https://i.sstatic.net/IHPQG.gif

I use this PNG: https://i.sstatic.net/GZl9O.png

I get this output: https://i.sstatic.net/U1i2H.gif

My code:

from PIL import Image

foreground = Image.open('image.gif')
background = Image.open('image.png').convert("RGBA")
img_w, img_h = background.size
foreground_w, foreground_w = foreground.size
if foreground.is_animated:
    frames = []
    for num in range(foreground.n_frames):
        foreground.seek(num)
        layer = Image.new('RGBA', (foreground_w, foreground_w), (0, 0, 0, 0)).resize((img_w, img_h))
        layer.paste(background, (0,0), mask=background)
        layer.paste(foreground.resize((img_w, img_h)), (0,0))
        frames.append(layer)
        frames[0].save('1.gif',
                    save_all=True,
                    append_images=frames[1:],
                    duration=100,loop=0)

Solution

  • Even though you call it a "Transparent GIF", there's not a single transparent pixel in it. The palette contains 16 colors, but 99.99% of each frame consists of the first 2 palette entries. The first 3 frames use 4 colors and the 4th uses 6.

    If the GIF contained proper transparency, a simple over = foreground.convert('RGBA') would give you an image with alpha transparency.