I am using the following code to get the R,G,B values for a grayscale image(they all will be the same) But the output gives me negative values.
Why is this so? I am totally confused.
for (int i=0;i<bb.getWidth();i++){
for (int j=0;j<bb.getHeight();j++){
long temp=bb.getPixel(i, j);
int a=(int)temp;
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(a );
byte[] result = b.array();
Log.d("gray value is=", String.valueOf((int)result[1]));
// Log.d("gray value is=", String.valueOf(getLastBytes(a)));
}
}
Here result[1] should correspond to the 'R' value. So how is it negative?
Try this
It is because of all type changes, the casting associated with it, and the fact that those types are signed.
First of all, the initial return value of
getPixel()
is anint
(32-bits or 4 bytes, one byte for ARGB). Placing it into a long seems unnecessary here, because you just cast it back into anint
. But so far so good.When you get the byte array, you are correct that the four bytes for ARGB are in order so
result[1]
should be the Red value. However, when you implicitly cast that byte into an int in your log statement, a problem happens.Because the
int
is four bytes long, and bothint
andbyte
are signed types, sign extension applies to the result, i.e.So when you print the result to the log, it interprets the decimal value of your data to be a negative number. Admittedly, even if you didn't cast and just printed the value of
byte
, that type is still signed (i.e. it goes from -128 to 127 and not 0 to 255, and 0x88 means -120), so the log output would be the same.If you want to log out the actual 0-255 value, modify your code to bitmask the pixel data to defeat sign extension in the
int
: