ImageIO.write 不保存为 gif,但适用于 jpg 和 png?

发布于 2024-07-14 09:51:56 字数 541 浏览 9 评论 0原文

我怀疑这里的解决方案可能非常简单,但我很困惑......

// 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

ImageIO.write() 不适用于 gif 吗? 这是否是对 gif 的某种回归,成为 Compuserve 专有的东西? 或者我只是愚蠢(我猜这是最后一个:))

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一片旧的回忆 2024-07-21 09:51:56

扩展 Iny 的答案:

基本上,你应该做的不是保存为 gif。 GIF 是 256 色调色图像(因此文件尺寸较小)。 如果您的图像具有超过 256 种颜色,则需要在尝试保存之前将颜色采样到 256。 编码器不会为你做这件事,因为它不知道该怎么做。 它可能会开始写入图像,一旦超过 256 色,就会退出。

我认为你可以这样做(伪代码)

// 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" );
}

如果你的绘图代码使用抗锯齿来看起来不错,那么你不需要考虑它就会增加颜色深度。 例如,在白色背景上绘制一条 AA 的蓝色对角线看起来有 2 种颜色:Color.WHITE 和 Color.BLUE,但如果仔细观察,您会发现有一大堆蓝色阴影可以消除对角线的锯齿状外观。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文