java ImageIO.write 不保存为 gif,但适用于 jpg 和 png?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/592032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ImageIO.write not saving out as gif, but works for jpgs and pngs?
提问by Yevgeny Simkin
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 :) )
ImageIO.write()对 gif不起作用?这是对 gif 是 Compuserve 专有的东西的某种回归吗?或者我只是愚蠢(我猜这是最后一个:))
采纳答案by iny
http://java.sun.com/javase/6/docs/api/javax/imageio/package-summary.html#gif_plugin_notes
http://java.sun.com/javase/6/docs/api/javax/imageio/package-summary.html#gif_plugin_notes
Note that GIF can only store 256 colors.
请注意,GIF 只能存储 256 种颜色。
回答by John Gardner
To expand on Iny's answer:
扩展 Iny 的回答:
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.
基本上,您应该做的不是保存为 gif。GIF 是一个 256 色的调色图像(因此它的文件很小)。如果您的图像有超过 256 种颜色,则在尝试保存之前,您需要将颜色采样到 256 种。编码器不会为你做这件事,因为它不知道该怎么做。它可能会开始写入图像,一旦超过 256 色,就会退出。
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.
如果您的绘图代码使用抗锯齿看起来不错,那将在您不考虑的情况下增加颜色深度。例如,在白色背景上绘制一条 AA 对角蓝线看起来是 2 种颜色,Color.WHITE 和 Color.BLUE,但是如果仔细观察,您会发现一大堆蓝色阴影可以消除对角线的锯齿状外观。

