为什么Java ImageIO会使JPEG颜色变平

时间:2009-08-13 12:32:37

标签: java jpeg javax.imageio

当我读取某些JPG文件时,颜色会变平。这是一个简单的例子,它读取jpg并将相同的图像写入另一个文件。

import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class JPegReadTest {
    public static void main(String[] args) {
        if (args.length == 2) {
            try {
                BufferedImage src = ImageIO.read(new File(args[0]));
                ImageIO.write(src, "jpg", new File(args[1]));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.err.println("Usage: java JPegReadTest src dest");
        }
    }
}

如果您使用例如http://www.flickr.com/photos/visualpanic/233508614/sizes/l/进行尝试,目标图像的颜色与源文件不同。这是为什么?如何解决?

还尝试将图像保存为png,但颜色也很淡(所以假设颜色信息无法正确读取)。

5 个答案:

答案 0 :(得分:10)

可能有几个原因。

  1. JPEG颜色数据通常存储为YCrCb而不是RGB,但转换应该几乎不会引起注意。
  2. JPEG通常具有嵌入的颜色配置文件,但许多应用程序不理解这一点而只是忽略它(在这种情况下,您的输出文件可能缺少颜色配置文件)。
  3. Java破坏后可能会重置或丢失Gamma值。
  4. 我实际上没有尝试过你的例子......请你在文件前后发帖吗?在没有实际检查结果文件的情况下,很难判断这些额外的数据是否存在。

    编辑:是的,很明显原始图像和转换后的图像具有不同的颜色配置文件。 Java剥离了原始的颜色配置文件,而是使用了通用的sRGB。它们在Windows上使用Firefox和各种程序看起来一样,因为这些程序在渲染器时不使用颜色配置文件。但是,在Mac上,Mac实际上支持这些颜色配置文件(在Mac上提供图形等方面的争论),因此它们呈现的方式不同。我没有Mac方便,但我怀疑如果你在任何平台上用Photoshop打开文件,你会看到差异。

答案 1 :(得分:2)

也许您的源图像具有指定的颜色配置文件,其色域宽于sRGB(如Adobe RGB),并且您的加载/保存周期不保留色彩空间信息?如果没有颜色配置文件,您的查看器将采用sRGB,压缩的色域将使所有内容看起来“啰嗦”。如果你有exiftool,

exiftool -ProfileDescription filename.jpg

是验证源和输出图像上颜色配置文件的快捷方法。

答案 2 :(得分:0)

jpeg是一种有损格式。在读入时,java将其存储为原始格式,就像BMP一样。然后它再次被写出来导致数据丢失。此外,在使用像GIMP这样的东西时,对质量的控制也很多。

或许考虑使用其他API,例如Image Magick,以便更好地控制质量。

答案 3 :(得分:0)

JPEGlossy格式。

这意味着如果你打开一个文件并再次保存它,你将失去一些信息,除非你采取非特定的步骤不丢失任何信息(在这种情况下可能的操作非常有限)。

此外ImageIO.write()可能会使用一些默认质量设置来保存JPEG文件,这可能会低于原始文件,这会导致质量下降。

尝试保存到PNG文件,您会发现它看起来与源文件相同。

答案 4 :(得分:0)

这是一个包含在ImageIO界面上扩展的源代码的链接 - 您可以在编写图像时更改质量和压缩参数.... http://www.universalwebservices.net/web-programming-resources/java/adjust-jpeg-image-compression-quality-when-saving-images-in-java