从Java BufferedImage getRGB()获取到的奇怪RGB值

4
我正在尝试从灰度图像中获取RGB值,但返回的RGB值不正确。以下是代码。
Color color = new Color(image.getRGB(0, 0));
System.out.print(color.getRed());
System.out.print(color.getGreen());
System.out.print(color.getBlue());

在使用一个颜色选择器时,第一个像素的RGB值为R:153,G:153,B:153,但我的代码却打印出了。
203203203

为什么会发生这件事?同时,我试图使用MATLAB灰度值来精确地获取像素值也是153。我做错了吗?
这是图片。

enter image description here


@FastSnail 这是我的灰度图像 https://drive.google.com/file/d/0BzWz7hgjG3VEUmhZdWlCYmdVQVk/view?usp=sharing - Ikhwan Nizwar A
2个回答

5
这是因为image.getRGB(x, y)根据定义返回sRGB颜色空间中的ARGB值。
JavaDoc中得知:

以默认的RGB颜色模型(TYPE_INT_ARGB)和默认的sRGB颜色空间返回整数像素。如果此默认模型与图像ColorModel不匹配,则进行颜色转换。

Matlab和其他工具可能使用线性RGB或灰度颜色空间,这就是数值不同的原因。
如果图像是灰度(TYPE_BYTE_GRAY),您可以通过访问Raster及其getDataElements方法来从Java中获取相同的值。
Object pixel = raster.getDataElements(0, 0, null); // x, y, data array (initialized if null)

如果图像是 TYPE_BYTE_GRAYpixel 将是一个包含单个元素的 byte 数组。
int grayValue = ((byte[]) pixel)[0] & 0xff;

在你的情况下,这个值将会是153


先生,我可以问一下为什么我们需要在末尾使用0xff掩码吗?我发现如果没有它,会出现完全不同的值... - Peter
1
@Peter 因为在Java中byte是有符号类型,而我们需要一个无符号值。 - Harald K

4

只需尝试此操作

System.out.println(image.getRaster().getSample(0, 0, 0));  //R
System.out.println(image.getRaster().getSample(0, 0, 1));  //G
System.out.println(image.getRaster().getSample(0, 0, 2));  //B

这里的

getSample(int x, int y, int b)
方法会返回位于 (x,y) 像素位置上指定波段的样本值,类型为int。[根据此文档]

参数:
x - 像素位置的 X 坐标
y - 像素位置的 Y 坐标
b - 要返回的波段
b = [0,1,2] 分别代表 [R,G,B]

同时查看一下BufferedImage getRGB vs Raster getSample


1
我看到一个编辑建议添加import java.awt.image.WritableRaster。getRaster()是BufferedImage类中的公共方法,它返回一个WritableRaster对象。你为什么建议进行编辑?你能再解释一下吗?@HawasKaPujaari - sifho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接