18

我一直在 javax.imageio.ImageIO 中使用 ImageIO.read() 和 ImageIO.write() 方法来读取和写入图像,我发现一些图像的颜色发生了奇怪的变化。

即使我将代码更改为只读取图像并写入它们(使用 jpeg、png、gif),所有这些新图像都有相同的问题。

我是否需要在 ImageIO.read/write 方法之前/之后添加任何其他代码?

这是我使用的代码:

    File f = new File("obw.jpg");
    BufferedImage bi = ImageIO.read(f);
    FileOutputStream fos2 = new FileOutputStream("obw2.jpg");
    ImageIO.write(bi, "JPG", fos2);
    FileOutputStream fos3 = new FileOutputStream("obw3.gif");
    ImageIO.write(bi, "GIF", fos3);
    FileOutputStream fos4 = new FileOutputStream("obw4.png");
    ImageIO.write(bi, "PNG", fos4);

我的环境:

    java version "1.6.0_35"
    MacOSX 10.8.2

原图: 在此处输入图像描述

读写后的图像之一:

在此处输入图像描述

4

2 回答 2

26

您的问题是 ImageIO 将 JPEG 中的 YCbCr 数据误解为 RBG 数据。相关的 Java 错误是47127974776576,Oracle 错误地声称这些错误已在 Java 1.4 中修复,但实际上仍然困扰着一些 Java 5、6 和 7 JVM。

在我从事的一个项目中,我们通过加载一个带有单个黑色像素的特殊构建的测试 JPEG 来解决这个问题,以查看 ImageIO 是否正确加载它。如果像素变为绿色,则 ImageIO 误解了图像数据,因此当我们稍后加载 JPEG 并检测到导致问题的 JPEG 类型时,我们还会应用颜色校正。(在 JVM 中触发问题的 JPEG 类型具有特定类型的二次采样且没有 JFIF 标记。)

这是一些处理该问题的LGPLv2 许可代码。当世界其他地方都设法正确加载 JPEG 时,需要这样的代码来解决数十年前的错误,这是我希望 Java 在火灾中死去的原因之一。

于 2014-01-07T19:56:51.093 回答
2

似乎是色彩空间问题,imageIO 尝试对图像进行一些编码/解码,但似乎失败了。看看这里: 无法使用 ImageIO.read(File file) 读取 JPEG 图像

于 2012-10-25T15:53:05.497 回答