Negative grayscale values - Bitmap

2019-08-11 09:50发布

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?

2条回答
姐就是有狂的资本
2楼-- · 2019-08-11 10:10

Try this

        long temp=bb.getPixel(i, j);
        R = Color.red(temp);
        G = Color.green(temp);
        B = Color.blue(temp);
查看更多
等我变得足够好
3楼-- · 2019-08-11 10:10

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 an int (32-bits or 4 bytes, one byte for ARGB). Placing it into a long seems unnecessary here, because you just cast it back into an int. 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 both int and byte are signed types, sign extension applies to the result, i.e.

  • The byte 0x48 will extend into an int as 0x00000048
  • The byte 0x88 will extend into an int as 0xFFFFFF88

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:

int red = (int)(result[1] & 0xFF);
Log.d("gray value is=", String.valueOf(red));
查看更多
登录 后发表回答