我一直在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
原始图片:
读写后的图像之一:
答案 0 :(得分:23)
您的问题是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在火灾中死亡的原因之一。
答案 1 :(得分:2)
似乎是一个色彩空间问题,imageIO尝试对图像进行一些编码/解码,但似乎失败了。看看这里: Unable to read JPEG image using ImageIO.read(File file)