2011-12-20 45 views
4

我有一个图像,称之为grayscale.jpg。现在我在The Gimp中打开该图像并将颜色模式更改为RGB并将其另存为color.jpg。如果我在任何图像查看器中查看grayscale.jpg和color.jpg,它们看起来完全一样。但是,如果我打开图像与javax.imageio.ImageIOjavax.imageio.ImageIO在灰度图像上读取不正确的RGB值

import javax.imageio.ImageIO; 

input = ImageIO.read(new File("grayscale.jpg")); 
System.out.format("Grayscale value: %x\n", input.getRGB(200, 200)); 

input = ImageIO.read(new File("color.jpg")); 
System.out.format("Color value: %x\n", input.getRGB(200, 200)); 

的彩色图像将返回正确的值,说0xff6c6c6c。灰度图像将返回像0xffaeaeae不同,更轻,不正确的值。

Grayscale value: 0xffaeaeae // Incorrect (Lighter) 
Color value:  0xff6c6c6c // Correct 

换句话说,javax.imageio.ImageIO中认为灰度图像轻得多比实际。我怎样才能准确读取灰度图像?

编辑

这里有更多的上下文。我的用户上传图片,可能是灰度。我的Java运行在服务器上并执行一些非常复杂的图像处理。所以一个理想的解决方案是修复我的Java代码,而不是用命令行工具来组合一些东西。

+0

更多的挖掘之后,这是 重复http://stackoverflow.com/questions/6474753/my-batch-jpg-resizer -works-with-color-images-but-grayscale-ones-become-washed-o – 2011-12-20 18:42:48

回答

-1

因为您使用JPEG,所以您的测试是无关紧要的,这是有损的。根据压缩情况,您可能有其他颜色值。所以,尝试与无损PNG相同。

您可以使用此图片来测试javax.imageio的正确性。使用Gimp将其转换为灰度,并确保将其保存为PNG。然后以相同的方式加载(这一个和转换后的)。并在for循环中比较y轴的所有颜色。

enter image description here

示例代码:

BufferedImage inputGrayscale = ImageIO.read(new File("grayscale.png"));  
BufferedImage inputColor = ImageIO.read(new File("color.png")); 

for (int i = 0; i < 256; ++i) 
{ 
    System.out.printf(i + "Grayscale value: %x\n", inputGrayscale.getRGB(10, i)); 
    System.out.printf(i + "Color value: %x\n", inputColor.getRGB(10, i)); 
    System.out.println(); 
} 
+0

这不仅仅是一个压缩的东西。如果我读取每个像素并将其写入文件,实质上是逐像素地复制图像,则彩色图像的副本看起来是正确的,而灰度图像的副本将比输入文件轻得多。 – 2011-12-20 17:49:45

+0

另请参阅我的编辑,其中添加更多上下文。这些图像来自我的用户,我不希望他们不必担心.png和.jpg。他们应该能够直接上传他们的相机输出。 – 2011-12-20 17:50:38