Android: How to get pixels of a single channel 16bit PNG Bitmap

浪尽此生 提交于 2019-12-06 15:13:49

问题


I have a png file created with python PIL that contains an height map (positive values).

The format is : single channel (grey level) at 16bit, thus 16 bit per pixel.

I read the file on android with BitmapFactory.decodeStream(<...data input stream...>);

I correctly get the size of the image through getWidth() and getHeight().

However when I loop though the pixels calling the getPixel(i,j) I obtain negative values, something like: -16776192 -16250872 -16250872 -16250872 -16250872 -16249848 ....

Instead I expect a positive value between 0 and 65535.

I discover that the value -16250872 in binary is 1111111111111111111111111111111111111111000010000000100000001000

This shows that the information relies on the first 16 least significant bits.

I tryed with getPixel(i,j)&0xffff and I obtain a plausible values, however I'm not sure about the endianess: should I to flip the 2 extracted bytes?

Is there a way to do it in more elegant and portable way this conversion ?

NOTE: the file is not a color (RGBA) PNG but a grey level PNG image with a single 16 bit value for each pixel.


回答1:


I found a solution by myself using the consideration made in this post: Android: loading an alpha mask bitmap

Basically, If you load directly a 16 bit greylevel PNG from bitmap factory the pixel format will be not correct. You need to use a RGBA 32 bit color format setting the pixel format to ARGB_8888. Then you have to get all the pixels with getPixel(i,j) and mask the integer value with 0xffff. In this way you will obtain the expected 16bit values.

This is a part of the code that I've used:

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig= Bitmap.Config.ARGB_8888;
Bitmap bmp=BitmapFactory.decodeStream(entity.getContent(),null,opt);
int W=bmp.getWidth();
int H=bmp.getHeight();
int px;
for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
    {
          px= bmp.getPixel(j, i)&0x0000ffff;//in px you will find a value between 0 and 65535
          ...
    }



回答2:


I assume your trying to get the RGB for a pixel in an image. If that is correct then you will find the following helpful.

Returns the Color at the specified location. Throws an exception if x or y are out of bounds (negative or >= to the width or height respectively).

That is the quote for the Bitmap.getPixel();

What you need to do to print this off so that it is human readable. I have programed with android, but not done this with android. I used the following function for one my programs.

public static int[] getRGBValue(BufferedImage bi, int x, int y) {
    int argb = bi.getRGB(x, y);
    int rgb[] = new int[] {
            (argb >> 16) & 0xff, // red
            (argb >>  8) & 0xff, // green
            (argb      ) & 0xff, // blue
    };
    return rgb;
}

public static String getStringOfRGB(int[] value) {
    return "Color: (" + value[0] + ", " + value[1] + ", " + value[2] + ")";
}

I don't kow what you trying to do exactly, so the code above won't answer your question... but should assist you in finding your answer on however you want to use the data of the pixel.

Hope this helps! :)



来源:https://stackoverflow.com/questions/10670017/android-how-to-get-pixels-of-a-single-channel-16bit-png-bitmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!