缓冲图像不一致的行为



在我使用 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

我认为它必须与伽马校正有关,但我在文档中找不到任何关于它的内容。

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

BufferedImage.getRGB() 方法总是在非线性sRGB 颜色空间 ( ColorSpace.CS_sRGB ( 中返回一种颜色(作为"打包格式"中的int(。无论您的图像具有什么色彩空间和每像素位数等,它都会这样做。因此,可能会发生转换和可能的精度损失。

来自JavaDoc:

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

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

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

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

因此,这里有轻微的精度损失,但没有什么意外。

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

您可以使用将 RGB 组件存储为字节(包括 0..255(的int指定的颜色。

但是图像的颜色模型不是RGB,而是BYTE_GRAY。显然,您可能会遭受精确损失。这解释了不同的颜色。如果您使用图像类型TYPE_INT_RGB则最终会得到相同的颜色。

最新更新