Skip to content

Instantly share code, notes, and snippets.

@iegik
Created July 19, 2012 11:39
Show Gist options
  • Save iegik/3143189 to your computer and use it in GitHub Desktop.
Save iegik/3143189 to your computer and use it in GitHub Desktop.
Converting PNG to GIF saving travsparent color
#!/usr/bin/env python
# Convert PNG images to GIF, preserving transparency
# 2008 - http://www.coderholic.com/png2gif
import sys
import Image
import random
import optparse
import os
import os.path
def unique_color(image):
"""find a color that doesn't exist in the image
"""
colors = image.getdata()
while True:
# Generate a random color
if image.mode == "LA":
color = random.randint(0, 255),
else:
color = (
random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255)
)
if color not in colors:
return color
def fill_transparent(image, color, threshold=0):
"""Fill transparent image parts with the specified color
"""
def quantize_and_invert(alpha):
if alpha <= threshold:
return 255
return 0
# Get the alpha band from the image
if image.mode == 'RGBA':
red, green, blue, alpha = image.split()
elif image.mode == 'LA':
gray, alpha = image.split()
# Set all pixel values below the given threshold to 255,
# and the rest to 0
alpha = Image.eval(alpha, quantize_and_invert)
# Paste the color into the image using alpha as a mask
image.paste(color, alpha)
def color_index(image, color):
"""Find the color index
"""
palette = image.getpalette()
palette_colors = zip(palette[::3], palette[1::3], palette[2::3])
index = palette_colors.index(color)
return index
def convert_image(image, name, new_name):
if image.mode == 'P':
if image.info.has_key('transparency'): # check to see if the image has any transparency
transparency = image.info['transparency']
image.save(new_name, transparency=transparency)
else: image.save(new_name)
elif image.mode == 'RGBA': # RGB images need to be converted to Palette mode
threshold = 0
colour = unique_color(image)
fill_transparent(image, colour, threshold)
image = image.convert('RGB').convert('P', palette=Image.ADAPTIVE)
image.save(new_name, transparency=color_index(image, colour))
elif image.mode == 'LA':
threshold = 0
colour = unique_color(image)
fill_transparent(image, colour, threshold)
image = image.convert('L').convert('P', palette=Image.ADAPTIVE)
image.save(new_name, transparency=color_index(image, (colour[0], colour[0], colour[0])))
else:
raise "Unsupported PNG file" + name + "(" + image.mode + ")"
p = optparse.OptionParser(description = 'Convert PNG images to GIF format',
usage = 'png2gif [OPTIONS] <files>')
p.add_option('--outputdir', '-o', default='.', help='Set the output directory in which to put the GIF images. Defaults to the current directory')
p.add_option('--threshold', '-t', default='0', help='Set the transparency threshold. Defaults to 0')
p.add_option('--replace', '-r', action='store_true', help='Delete the PNG files after converting them to GIF')
p.add_option('--verbose', '-v', action='store_true', help='Verbose output')
options, arguments = p.parse_args()
# Check that the specified output directory exists
if not os.path.exists(options.outputdir):
if options.versbose: print "Creating output directory", options.outputdir
try:
os.mkdir(options.outputdir)
except:
print "Cannot create output directory", options.outputdir
print "Please specifiy a different directory"
exit
for x in arguments:
# Make sure we have the correct extension
extension = x[-3:]
if extension != "png":
print "Invalid file extension for ", x, ". Expecting png found ", extension
continue
image = Image.open(x)
if options.verbose:
print "Converting", x, "to", x[:-3] + "gif"
try:
convert_image(image, x, options.outputdir +os.sep + x[:-3] + "gif")
if options.replace:
if options.verbose: print "Removing", x
os.remove(x)
except:
print "Problem converting",x, "- skipping"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment