只有ImageIO.read()和ImageIO.write()后,jpeg图像颜色才会大幅改变

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

在我工作的项目中,我们通过加载一个带有单个黑色像素的特殊构造的测试JPEG来处理这个问题,以查看ImageIO是否正确加载它。 如果像素显示为绿色,则ImageIO会错误解释图像数据,因此当我们稍后加载JPEG并检测导致问题的JPEG类型时,我们也会应用颜色校正。 (在JVM中触发问题的JPEG类型具有特定类型的子采样而没有JFIF标记。)

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

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