BufferedImage's immediate behavior
After I set the java.awt.image.BufferedImage pixel to a value using setRGB, the subsequent getRGB call returns a different value than what I set.
code:
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);
It produces the following output
-16711423
-16777216
I think it should do something with gamma correction, but I couldn't find anything about it in the documentation.
Ideally, I want to change this behavior to return the same value as me. Is it possible?
source to share
The method BufferedImage.getRGB()
always returns a color (as int
in "packed format") in the sRGB ( ColorSpace.CS_sRGB
) non-linear color space . It will do it no matter what color space and bit per pixel, etc. Have your image. Thus, conversion and possible loss of accuracy can occur.
From JavaDoc :
Returns an integer pixel in the standard RGB color model (TYPE_INT_ARGB) and the default sRGB color space. Color conversion occurs if this default model does not match the ColorModel image.
Your image TYPE_BYTE_GRAY
internally uses a linear gray color space ( ColorSpace.CS_GRAY
) which does not map one-to-one to sRGB.
Also, I suggest using hexadecimal notation for (A) RGB colors, which makes it much easier to display colors and differences:
-16711423 == 0xff010101
-16777216 == 0xff000000
So, there is a slight loss of precision here, but nothing unexpected.
If you need direct access to pixel data, look at the classes Raster
, SampleModel
and DataBuffer
(and their corresponding subclasses).
source to share
You specify a color specified with int
which stores RGB components as bytes (in the range 0..255 inclusive).
But the color model of your image is not RGB, but BYTE_GRAY
. Obviously, you can lose precision. This explains the different colors. If you were using the image type TYPE_INT_RGB
, you would be in the same color.
source to share