简体   繁体   中英

How to convert PNG images to a transparent GIF?

I'm trying to convert a list of PNG images with a transparent background to a GIF, while keeping the background transparency. I took this bit of code I found, and adapted it:

import os
from PIL import Image

# Create the frames
frames = []

path = "directory/to/my/png/images"
for frame in os.listdir(path):
    new_frame = Image.open(path + "/" + frame)
    frames.append(new_frame)

# Save into a GIF file
frames[0].save(path + "/../output/animation.gif", format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=41, loop=1, transparency=0)

It is opening all the PNG images I have in a folder, and export them to a GIF, but the background is black. I have looked at the PIL documentation , but I don't seem to understand how the transparency parameter works, or I think I am using it wrong.

First of all, the GIF format does not support alpha-channel transparency like PNG does. You can only select one out of the 256 possible colors in a GIF to be transparent . So, you also don't get any smooth transparencies, pixels are either fully transparent or opaque.

When dealing with Image objects having mode RGBA , try to convert all your images to mode PA before saving. Maybe, that helps automagically .

Let's assume we have the following three images:

红色的

绿色的

蓝色的

Your minimized code would look like this:

from PIL import Image

frames = [Image.open('red.png'), Image.open('green.png'), Image.open('blue.png')]

frames[0].save('test.gif', format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=200, loop=0, transparency=0)

The resulting GIF in fact doesn't reflect the transparency from the single PNGs, the GIF is totally corrupted:

损坏的输出

Adding the conversion to mode PA , the code might look like this:

from PIL import Image

frames = [Image.open('red.png'), Image.open('green.png'), Image.open('blue.png')]

frames = [frame.convert('PA') for frame in frames]

frames[0].save('test.gif', format='GIF',
               append_images=frames[1:],
               save_all=True,
               duration=200, loop=0, transparency=0)

And, the result is fine, transparency is maintained:

适当的输出

I don't know, if that route works for arbitrary PNGs, but it's worth testing with your images, isn't it? If that doesn't work, you need to provide some of your input images for further testing.

The final approach could be to replace all transparent pixels in your PNGs with a certain color, let's say solid yellow. When saving the GIF later, you'd need to make sure, that all images' palettes store that solid yellow at the same index, and then finally set transparency to that index.

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
Pillow:        8.1.0
----------------------------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM