iegik
7/19/2012 - 11:39 AM

Converting PNG to GIF saving travsparent color

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"