简体   繁体   English

Android:如何获取单通道16bit PNG位图的像素

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

I have a png file created with python PIL that contains an height map (positive values). 我有一个用python PIL创建的png文件,其中包含一个高度图(正值)。

The format is : single channel (grey level) at 16bit, thus 16 bit per pixel. 格式为:16位单通道(灰度级),因此每个像素16位。

I read the file on android with BitmapFactory.decodeStream(<...data input stream...>); 我使用BitmapFactory.decodeStream(<...data input stream...>);在android上读取了文件

I correctly get the size of the image through getWidth() and getHeight() . 我正确地通过getWidth()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 .... 但是,当我循环遍历调用getPixel(i,j)的像素时getPixel(i,j)我获得了负值,例如:-16776192 -16250872 -16250872 -16250872 -16250872 -16249848 ....

Instead I expect a positive value between 0 and 65535. 相反,我期望一个介于0和65535之间的正值。

I discover that the value -16250872 in binary is 1111111111111111111111111111111111111111000010000000100000001000 我发现二进制值-16250872是1111111111111111111111111111111111111111111000010000000100000001000

This shows that the information relies on the first 16 least significant bits. 这表明该信息依赖于前16个最低有效位。

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? 我尝试使用getPixel(i,j)&0xffff并获得了一个合理的值,但是我不确定字节序:我应该翻转提取的2个字节吗?

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. 注意:该文件不是彩色(RGBA)PNG,而是具有每个像素单个16位值的灰度PNG图像。

I found a solution by myself using the consideration made in this post: Android: loading an alpha mask bitmap 我使用本文中的注意事项自行找到了解决方案: Android:加载alpha蒙版位图

Basically, If you load directly a 16 bit greylevel PNG from bitmap factory the pixel format will be not correct. 基本上,如果直接从位图工厂加载16位灰度PNG,则像素格式将不正确。 You need to use a RGBA 32 bit color format setting the pixel format to ARGB_8888. 您需要使用RGBA 32位颜色格式,将像素格式设置为ARGB_8888。 Then you have to get all the pixels with getPixel(i,j) and mask the integer value with 0xffff. 然后,您必须使用getPixel(i,j)获取所有像素,并使用0xffff屏蔽整数值。 In this way you will obtain the expected 16bit values. 这样,您将获得预期的16位值。

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
          ...
    }

I assume your trying to get the RGB for a pixel in an image. 我假设您尝试获取图像中像素的RGB。 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). 如果x或y超出范围(分别为宽度或高度的负值或> =),则引发异常。

That is the quote for the Bitmap.getPixel(); 那是对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. 我已经用android编程了,但是没有用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! 希望这可以帮助! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM