java - jpeg 图像颜色在 ImageIO.read() 和 ImageIO.write() 之后发生了巨大变化

标签 java image image-processing

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

原始图片: enter image description here

读写后的图片之一:

enter image description here

最佳答案

您的问题是 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 - jpeg 图像颜色在 ImageIO.read() 和 ImageIO.write() 之后发生了巨大变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13072312/

相关文章:

java - 如何在 JavaFX 中创建图例(图表边框中的文本)

java - 这个方法抛出异常会不会导致内存泄漏?

java - 调用字节码类方法,java

python - 通过Canny和Hough进行视线检测

opencv - opencv 中对 `cv::imread(std::string const&, int)' 的 undefined reference

java - 从 HashMap 中查找对象键

Java 图像 slider ?

c# - 在将 Thread.Sleep 与 pictureBox 一起使用时,Winform 卡住

javascript - 如何在后台加载新的material.map.image.src然后渲染

swift - 在 Swift 中为 UIImage 着色