Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageIO.write not saving out as gif, but works for jpgs and pngs?

I suspect the solution here is probably really simple, but I'm stumped...

// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);

// fill image data (works fine)
ImageIO.write(bufferedImage, "JPG", f1); // works fine
ImageIO.write(bufferedImage, "PNG", f2); // works fine
ImageIO.write(bufferedImage, "GIF", f3); // this returns false, creates a broken gif file, but fires no exceptions

Does ImageIO.write() not work for gifs? is this some sort of throwback to gif being a proprietary Compuserve thing? Or am I just being stupid (I'm guessing it's the last one :) )

like image 412
Yevgeny Simkin Avatar asked Feb 26 '09 19:02

Yevgeny Simkin


1 Answers

To expand on Iny's answer:

What you should be doing is not saving as gif, basicly. GIF is an 256 color palleted image (hence its small file size). If your image has more than 256 colors, you need to downsample the colors to 256 before trying to save. the encoder doesn't do it for you, because it doesn't know what to do. it probably starts writing the image, and once it exceeds 256 colors, just bails out.

I think you could kindof do it like this (psuedocode)

// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);

... //fill image data (works fine)

ImageIO.write(bufferedImage, "JPG", f1); // works fine

ImageIO.write(bufferedImage, "PNG", f2); //works fine

// downsample to lower color depth by using BYTE_RGB?
BufferedImage crappyImage = new BufferedImage(w,h,BufferedImage.TYPE_BYTE_RGB);
crappyImage.getGraphics().drawImage(bufferedImage, 0, 0, w, h, null);
// or you could repeat the drawing code above with less colors


if (!ImageIO.write(crappyImage , "GIF", f3))
{
   //still too many colors
   f3.delete();
   showError( "Could not save as gif, image had too many colors" );
}

If your drawing code is using Antialiasing to look nice, that will increase the color depth without you thinking about it. For example, drawing an AA'd diagonal blue line on a white background would appear to be 2 colors, Color.WHITE and Color.BLUE, but if you look closely, you have a whole bunch of shades of blue to get rid of the jaggy appearance of the diagonal line.

like image 144
John Gardner Avatar answered Sep 18 '22 01:09

John Gardner