【问题标题】:jpeg image color gets drastically changed after just ImageIO.read() and ImageIO.write()jpeg 图像颜色在 ImageIO.read() 和 ImageIO.write() 之后发生了巨大变化
【发布时间】:2012-10-15 20:33:19
【问题描述】:

我一直在 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

原图:

读写后的一张图片:

【问题讨论】:

  • 哪一个被改变了,还是全部改变了?原始图像是否可能损坏
  • 我阅读了原始图像并写了 jpeg、png、gif 图像,这三个图像都显示绿色 obiwan...有什么方法可以检查原始图像是否损坏?
  • lesto,我尝试使用光栅(使用 JPEGImageReader,而不是 Sanselan 库),但该代码给出了 ArrayOutOfBoundsException,这不是读取 CMYK 图像时发生的行为..

标签: java image image-processing


【解决方案1】:

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

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

这里有一些LGPLv2-licensed code 可以解决这个问题。当全世界都设法正确加载 JPEG 时,需要这样的代码来解决已有十几年历史的错误,这是我希望 Java 在火灾中死去的原因之一。

【讨论】:

  • 谢谢!!我现在感觉更安全了!
  • 仍未修复 - 我在 Java 8 上看到了这个问题。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 2022-08-21
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多