BufferedImage行为不一致

时间:2014-09-17 11:44:33

标签: java image image-processing awt bufferedimage

使用setRGB将java.awt.image.BufferedImage的像素设置为某个值后,对getRGB的后续调用将返回与我设置的值不同的值。

代码:

BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY);
int color1 = -16711423; // corresponds to RGB(1, 1, 1)
image.setRGB(0, 0, color1);
int color2 = image.getRGB(0, 0);
System.out.println(color1);
System.out.println(color2);

它产生以下输出

-16711423
-16777216

我认为它必须对伽马校正做些什么,但我在文档中找不到任何相关内容。

理想情况下,我想更改此行为以返回与我设置的值相同的值。这可能吗?

2 个答案:

答案 0 :(得分:3)

BufferedImage.getRGB()方法始终以非线性 sRGB 颜色返回颜色(作为“压缩格式”中的int)空间(ColorSpace.CS_sRGB)。无论您的图像具有什么颜色空间和每像素位等,它都会这样做。因此,可能发生转换和可能的精度损失。

来自JavaDoc

  

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

您的TYPE_BYTE_GRAY图片内部使用线性灰色空间(ColorSpace.CS_GRAY),该空间不会与sRGB一对一地映射。

另外,我建议对(A)RGB颜色使用十六进制表示法,它使颜色和差异更容易看到:

-16711423 == 0xff010101
-16777216 == 0xff000000

所以,这里有一个小的精度损失,但没有任何意外。

如果您想直接访问像素数据,请查看RasterSampleModelDataBuffer类(及其各自的子类)。

答案 1 :(得分:0)

您可以设置一个用int指定的颜色,该颜色将RGB分量存储为字节(范围为0..255)。

但是图像的颜色模型不是RGB而是BYTE_GRAY。显然你可能会遭受精确失败。这解释了不同的颜色。如果您使用了图像类型TYPE_INT_RGB,您将会以相同的颜色结束。