4

Im trying to get RGB value from a grayscale image and it was return wrong(?) RGB value. Here is the code.

Color color = new Color(image.getRGB(0, 0));
System.out.print(color.getRed());
System.out.print(color.getGreen());
System.out.print(color.getBlue());

At a color picker was using, the first pixel RGB value R:153,G:153,B:153 but my code print

203203203

Why this thing happened? And also, im trying to use MATLAB Grayscale values for the exact pixel is also 153. Am i doing this wrong?

this is the image

enter image description here

Madhawa Priyashantha
  • 9,633
  • 7
  • 33
  • 60

2 Answers2

5

This is because image.getRGB(x, y) by definition returns ARGB values in sRGB colorspace.

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.

Matlab and other tools likely use a linear RGB or gray color space, and this is why the values are different.

You can get the same values from Java if the image is gray scale (TYPE_BYTE_GRAY), by accessing the Raster and its getDataElements method.

Object pixel = raster.getDataElements(0, 0, null); // x, y, data array (initialized if null)

If the image is TYPE_BYTE_GRAY, pixel will be a byte array with a single element.

int grayValue = ((byte[]) pixel)[0] & 0xff;

This value will be 153 in your case.

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • Sir, may I ask you why we need the 0xff mask at the end? I realized that without it, a totally different value appears... – Peter Oct 06 '18 at 15:25
  • 1
    @Peter Because byte is a signed type in Java, and we want an unsigned value. – Harald K Oct 06 '18 at 15:28
4

Just try this

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

Here

getSample(int x, int y, int b)
Returns the sample in a specified band for the pixel located at (x,y) as an int. [According to this]

Parameters:
x - The X coordinate of the pixel location
y - The Y coordinate of the pixel location
b - The band to return
b = [0,1,2] for [R,G,B]

and also take a look at BufferedImage getRGB vs Raster getSample

Community
  • 1
  • 1
sifho
  • 645
  • 5
  • 10
  • 1
    I have seen an edit suggest to add import java.awt.image.WritableRaster. getRaster() is a public method in BufferedImage class which returns a WritableRaster object. Why did you suggest the edit? Can you explain a little more? @HawasKaPujaari – sifho Sep 27 '15 at 07:04