javax.imageio.ImageIO读取灰度图像上不正确的RGB值

Dav*_*ith 5 java image

我有一张图片,称其为grayscale.jpg。现在,我在Gimp中打开该图像,并将颜色模式更改为RGB,并将其另存为color.jpg。如果我在任何图像查看器中查看grayscale.jpg和color.jpg,它们的外观将完全相同。但是如果我用打开图像javax.imageio.ImageIO

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));
Run Code Online (Sandbox Code Playgroud)

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

Grayscale value: 0xffaeaeae // Incorrect (Lighter)
Color value:     0xff6c6c6c // Correct
Run Code Online (Sandbox Code Playgroud)

换句话说,javax.imageio.ImageIO认为灰度图像比它们实际的要轻得多。如何准确读取灰度图像?

编辑

这里有更多背景信息。我的用户上传的图像可能是灰度图像。我的Java在服务器上运行,并执行一些非常复杂的图像处理。因此,理想的解决方案是仅修复我的Java代码,而不是使用命令行工具将某些内容混为一谈。

Mar*_*aux -1

您的测试无关紧要,因为您使用的是有损的 JPEG。根据压缩情况,您可能有其他颜色值。因此,尝试对无损的 PNG 进行同样的操作。

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

在此输入图像描述

示例代码:

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();
}
Run Code Online (Sandbox Code Playgroud)