Java GIF transparency stuff

Still alive.

At work last week we had a problem with transparent GIFs. Our Java program needed to be able to resize images. However, the approach taken worked with all tested formats except transparent GIFs.

After searching the internet for a while, I was able to piece together a solution that a) worked and b) avoided unnecessarily allocating memory (which was a “feature” of most other solutions I found). It appears this is a relatively common problem, maybe some lost soul in a similar situation will find it helpful.

The nature of our program was that the image content was loaded, transformed and saved. The loading and saving was performed by the Java ImageIO class, and it is possible that these steps are unnecessary if you are using a custom image codec library. I didn’t look into it too deeply.

This is the solution, minus the details of our image manipulation. It lives in a static Image Utility class.

 * The ever problematic GIF format needs special handling. 
 * If the background colour is not cleared to the transparent colour the image loses transparency.
private static void handleGifTransparency(
	BufferedImage output,
	ColorModel colourModel,
	Graphics2D graphics) throws IOException
	if(colourModel instanceof IndexColorModel)
		IndexColorModel indexed = (IndexColorModel)colourModel;

		int index = indexed.getTransparentPixel();
		if(index == -1)
			// Should never happen, caller checks if image is opaque.
			throw new IOException("no alpha pixel with transparent PNG");
		int r = indexed.getRed(index);
		int b = indexed.getBlue(index);
		int g = indexed.getGreen(index);
		Color c = null;
			int a = indexed.getAlpha(index);
			c = new Color(r,g,b,a);
			c = new Color(r,g,b);
		graphics.clearRect(0, 0, output.getWidth(), output.getHeight());

private static BufferedImage modify(
	BufferedImage input,
	int width,
	int height,
	String format) throws IOException
	ColorModel colourModel = input.getColorModel();
	BufferedImage output = new BufferedImage(colourModel, colourModel.createCompatibleWritableRaster(width, height), input.isAlphaPremultiplied(), null);
	Graphics2D graphics = output.createGraphics();
		if(format.equals("gif") && output.getTransparency() != Transparency.OPAQUE)
			handleGifTransparency(output, colourModel, graphics);

		// Whatever you want to do here
	return output;

If you happen to know a less ugly method, let me know!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: