Friday, July 20, 2007

Transparent gifs in Java

The people at SUN added gif support in Java 6.0 but they did such a poor job that we all should get some baseball bats and visit their headquarter: Not only did they forget to implement a reasonable quantizer (to reduce millions of colors to the 256 of the gif format) but they also have forgotten to support transparency or the A in RGBA. Additionally treating their IndexColorModel as an unwanted step child doesn't make it better neither...

So here is the code to write transparent gifs out of an RGBA Java image using Java 6.0:


ImageIO.write(convertRGBAToIndexed(sig.getImage()), "gif",);

public static BufferedImage convertRGBAToIndexed(BufferedImage src) {
BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
Graphics g = dest.getGraphics();
g.setColor(new Color(231,20,189));
g.fillRect(0, 0, dest.getWidth(), dest.getHeight()); //fill with a hideous color and make it transparent
dest = makeTransparent(dest,0,0);
dest.createGraphics().drawImage(src,0,0, null);
return dest;
}

public static BufferedImage makeTransparent(BufferedImage image, int x, int y) {
ColorModel cm = image.getColorModel();
if (!(cm instanceof IndexColorModel))
return image; //sorry...
IndexColorModel icm = (IndexColorModel) cm;
WritableRaster raster = image.getRaster();
int pixel = raster.getSample(x, y, 0); //pixel is offset in ICM's palette
int size = icm.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
return new BufferedImage(icm2, raster, image.isAlphaPremultiplied(), null);
}



8 Comments:

Anonymous Anonymous said...

Great entry. I was wondering what the heck was wrong with gifs until I found this entry. The technique works well. One thing I did notice is the edges in the resulting image are a bit rough compared to the original. Do you know of a way to smooth them out?

7:20 PM

 
Anonymous Anonymous said...

Never mind. I realized that ragged edges are the nature of the beast, when dealing with gif's ;) Thanks again.

7:02 AM

 
Blogger Unknown said...

thank you 10^100 times. You saved my weekend!!!

10:07 AM

 
Blogger Artem Stasuk said...

Thanks. That's supper.

4:02 PM

 
Blogger Unknown said...

Thanks a lot German, this saved me a big headache!

9:05 AM

 
Blogger Wojciech Seliga said...

Thanks man! The most concrete post on this subject in the net.

1:17 PM

 
Anonymous Anonymous said...

Thanks a lot, it works! Petr

1:19 PM

 
Blogger Unknown said...

It works also for png images, not only for gifs. Very usefull piece of the code, especially for mobile purposes :) Thanks for it.

10:52 AM

 

Post a Comment

<< Home