PIL Tutorial: Converting Between PNG and GIF
PIL supports both PNG and GIF image formats, but converting between the two while keeping transparency can be tricky. Inside is a list of tips for dealing with transparency and dithering issues when processing GIF image formats in PIL. If you are only interested in the final solution you can skip this tutorial and go directly to the code
Saving GIF with transparency
Support for writing GIF transparency was added in PIL1.1.4. Yet the latest PIL version 1.1.6 doesn't not automatically write the transparency index for you. In order to keep the transparency, you need to explicitly specify the transparent color index as an option when saving the image in GIF format.
im = Image.open('icon.gif') transparency = im.info['transparency'] im.save('icon.gif', transparency=transparency)
im.info is a dictionary that contains a set of properties defined by the Image.open method.
Converting from GIF into PNG
Luckily PNG supports palette-based images. This will save us from a lot of work. The only thing you have to do is setting the transparency option.
im = Image.open('icon.gif') transparency = im.info['transparency'] im .save('icon.png', transparency=transparency)
Converting from PNG into GIF
This can be tricky for two reasons:
- PNG gives a much wider range of color depths than GIF, truecolor up to 48-bit compared to 8-bit 256-color.
- PNG gives a much wider range of transparency options than GIF, including alpha channel transparency.
PNG image is palette-based
If the PNG image is palette-based, i.e. P mode, then the conversion is straightforward. The only thing you have to do is setting the transparency option as before:
im = Image.open('icon.png') assert im.mode == 'P' transparency = im.info['transparency'] im .save('icon.gif', transparency=transparency)
PNG image is in RGBA mode
When converting form RGBA into P, we need to reduce the number of distinct colors used in the image to a maximum of 256 colors through a process called quantization.
PIL supports two types of palette quantizers, WEB and ADAPTIVE. The default quantizer in PIL1.1.6 is Image.WEB which reduces the color space to web safe colors and dithers the rest. While Image.ADAPTIVE quantizer is intended to keep the converted image as visually similar as possible to the original image.
The following table explains the difference in output between WEB and ADAPTIVE quantizers in PIL:
| PNG: Original Image | GIF: WEB quantizer | GIF: ADAPTIVE quantizer |
|---|---|---|
![]() |
![]() |
![]() |
So to avoid dithering, we should use the ADAPTIVE quantizer like this:
im = Image.open('mouse.png') im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE) im.save('mouse.gif')
Now that we know how to solve the first issue, we need to find a solution for the transparency issue.
Solid background workaround
Sometimes you don't need to keep the transparency; all what you want is a solid background. This will do the trick for you:
im = Image.open('mouse.png') # Create a new image with a solid color background = Image.new('RGBA', im.size, (255, 255, 255)) # Paste the image on top of the background background.paste(im, im) im = background.convert('RGB').convert('P', palette=Image.ADAPTIVE) im.save('mouse.gif')

Solution for keeping transparency
GIF allows you to set one of the colors in the palette as fully transparent, whereas PNG images in RGBA mode allow you to have different levels of transparency through the alpha band. An alpha value of 255 means the pixel is fully opaque, 0 means fully transparent and Intermediate values indicate partially transparent pixels.
Let's try to set the black background to transparent:
im = Image.open('mouse.png') im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE) # The black index in the palette of this image is 255 im.save('mouse.gif', transparency=255)

In addition to the background, black is also used in other places in the image, such as the eyes. That's why the result is bad. A solution to this is to fill the transparent parts with a unique color that doesn't exist in other opaque parts.
The solution
The trick is to use the colors keyword argument in im.convert. This argument tells convert how many colors it should use in the palette. The default is 256 which is the maximum possible number of colors in the palette. To reserve a color in the palette for transparency we can tell convert to only use 255 out of 256 and then use the last index 255 to fill the transparent parts.
from PIL import Image im = Image.open('mouse.png') # Get the alpha band alpha = im.split()[3] # Convert the image into P mode but only use 255 colors in the palette out of 256 im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) # Set all pixel values below 128 to 255, # and the rest to 0 mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0) # Paste the color of index 255 and use alpha as a mask im.paste(255, mask) # The transparency index is 255 im.save('mouse.gif', transparency=255)
We used the paste function to fill the transparent parts with the last reserved index. For more examples on using the paste function please refer to PIL Tutorial: How to Create a Button Generator.
And here is the final result:

- 14130 reads






Comments
Command line utility
Hi Nadia,
A great post, with some really good code samples. I've created a PNG2GIF command line utility that's based on your code, which makes it really simple to convert multiple PNG images to GIF. You can download it at http://www.coderholic.com/png2gif/
I really liked your other PIL post, and hope to see some more in the future!
Thanks, Ben
Thanks for sharing
Hi Ben,
I'm glad you liked the post. The command line utility you created is very simple and really helpful.
Thanks for sharing :)
Hi do you know what the save
Hi do you know what the save options are in pil?
save options
Save options differ between image formats. You may refer to the PIL handbook for the full list of options. Here are the PNG format options:
http://www.pythonware.com/library/pil/handbook/format-png.htm
I am looking for the solution
I am looking for the solution of creating animated gif from PIL, so got your page and http://svn.effbot.org/public/pil/Scripts/gifmaker.py.
yes, gifmaker.py can help me create animated gif, but all frames will show without delay, do you have any advice, thanks in advance.
There is a GIF save option
There is a GIF save option called duration. This option allows you to change the delay between frames:
http://www.pythonware.com/library/pil/handbook/format-gif.htm
Opening the resulting gif and then saving it with a delay might just work.
I cannot use gifmaker.py...could you help to check the mistake?
I want to convert a series of PNG to a GIF.
but i am a rookie..when i used the gifmaker.py script,I met some mistakes,could you help me ?
Traceback (most recent call last):
File "D:\python资料\Python-image\程序\try.py", line 22, in
gifmaker.makedelta(fp, sequence)
File "D:\python资料\Python-image\程序\gifmaker.py", line 79, in makedelta
for s in getheader(im) + getdata(im):
File "C:\Python25\Lib\site-packages\PIL\GifImagePlugin.py", line 349, in getheader
s.append(im.im.getpalette("RGB")[:maxcolor*3])
AttributeError: 'NoneType' object has no attribute 'getpalette'
Many thank you's!
This did the trick, and all from python. I needed to create compact images of scientific data colormapped for Google Earth overlaying. Palette PNG offers enough colors with transparency and file size compactness to animate time-varying datasets for folks over the web.
PIL patch for transparency
When using these PIL tips along with django & sorl (http://code.google.com/p/sorl-thumbnail/) to make thumbnails, I was having some issues preserving transparency (sometimes artifacts, sometimes white).
In case anyone else is having a similar problem, there's a recent patch for sorl that fixes this:
* http://code.google.com/p/sorl-thumbnail/issues/detail?id=56
photo animation
thanks for the tutorial i've learned a lot.... well, it's not really that easy to convert a PNG file into GIF or vice-versa..... well that's for me... anyway thank you.... i am also into photo animation and i usually use http://www.wegif.com/
Gif Photo Animation
Post new comment