tags:

views:

3377

answers:

2

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 :) )

+3  A: 

http://java.sun.com/javase/6/docs/api/javax/imageio/package-summary.html#gif_plugin_notes

Note that GIF can only store 256 colors.

iny
umm... I'm not sure what I'm looking at there... If it makes sense to you, I don't suppose you'd be kind enough to translate this into an instruction or two as to what I should actually be "doing"?
Dr.Dredel
I'm not sure what you are getting. RGB image can't be just saved to GIF, maybe you could use different kind of image?
iny
+4  A: 

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.

John Gardner
TYPE_BYTE_RGB is not a member of BufferedImage. TYPE_BYTE_INDEXED (which the java doc seems to suggest as an alternative) does not produce any changes to my results. However, I think I'm just going to skip the gifs and move on to more important problems since no one uses gifs anymore, anyway :)
Dr.Dredel
thats why i said it was psuedocode :) Therea re others like TYPE_3BYTE_BGR and TYPE_USHORT_555_RGB. The closest would be TYPE_BYTE_INDEXED, from what im reading in the BufferedImage javadocs
John Gardner