After I set a pixel of a java.awt.image.BufferedImage to a value using setRGB, a subsequent call to getRGB returns a different value than 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 has to 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 I set. Is that possible?
The BufferedImage.getRGB()
method, always returns a color (as an int
in "packed format") in the non-linear sRGB color space ( ColorSpace.CS_sRGB
). It will do so, regardless of what color space and bits per pixel etc. your image has. Thus, conversion and possible precision loss may occur.
From the JavaDoc :
Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace. Color conversion takes place if this default model does not match the image ColorModel.
Your TYPE_BYTE_GRAY
image internally uses a linear gray color space ( ColorSpace.CS_GRAY
), which does not map one-to-one with sRGB.
Also, I suggest using hexadecimal notation for (A)RGB colors, it makes the colors and difference much easier to see:
-16711423 == 0xff010101
-16777216 == 0xff000000
So, there is a minor precision loss here, but nothing unexpected.
If you want direct access to the pixel data, look into the Raster
, SampleModel
and DataBuffer
classes (and their respective subclasses).
You set a color specified with an int
which stores RGB components as bytes (in the range of 0..255 inclusive).
But the color model of your image is not RGB but BYTE_GRAY
. Obviously you may suffer precision losing. This explains the different colors. Should you have used image type TYPE_INT_RGB
you would've ended up with the same color.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.