我一直在使用 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
原始图片:
读写后的图片之一:
最佳答案
您的问题是 ImageIO 将 JPEG 中的 YCbCr 数据误解为 RBG 数据。相关的 Java 错误是 4712797和 4776576 ,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/