【问题标题】:Android: How to get pixels of a single channel 16bit PNG BitmapAndroid:如何获取单通道 16 位 PNG 位图的像素
【发布时间】:2012-05-27 01:18:15
【问题描述】:

我有一个使用 python PIL 创建的 png 文件,其中包含一个高度图(正值)。

格式为:单通道(灰度)16bit,即每像素16bit。

我用BitmapFactory.decodeStream(<...data input stream...>);在android上读取了文件

我通过getWidth()getHeight()正确得到了图片的大小。

但是,当我循环调用getPixel(i,j) 的像素时,我会得到负值,例如:-16776192 -16250872 -16250872 -16250872 -16250872 -16249848 ....

相反,我期望一个介于 0 和 65535 之间的正值。

我发现二进制值 -16250872 是 1111111111111111111111111111111111111111000010000000100000001000

这表明信息依赖于前 16 个最低有效位。

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

有没有办法以更优雅和便携的方式进行这种转换?

注意:该文件不是彩色 (RGBA) PNG,而是灰度 PNG 图像,每个像素都有一个 16 位值。

【问题讨论】:

  • 你得到否定的原因是因为它是一个打包的值。例如:白色 (255,255,255,255) 将被包装为 11111111 11111111 11111111 11111111
  • 是的,我知道。例如,在 32bpp 像素 RGBA 位图中,像素存储为 4 字节(0 到 255 之间的值)打包成 32 位整数。但是我有一个 16 bpp、单通道 PNG 和单色通道(灰色电平)。获得该值的正确方法是什么?

标签: java android bitmap png 16-bit


【解决方案1】:

我自己使用这篇文章中的考虑找到了一个解决方案: Android: loading an alpha mask bitmap

基本上,如果您从位图工厂直接加载 16 位灰度 PNG,则像素格式将不正确。您需要使用 RGBA 32 位颜色格式,将像素格式设置为 ARGB_8888。然后您必须使用 getPixel(i,j) 获取所有像素,并使用 0xffff 屏蔽整数值。这样,您将获得预期的 16 位值。

这是我使用的代码的一部分:

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】:

我假设您尝试获取图像中像素的 RGB。如果这是正确的,那么您会发现以下内容很有帮助。

返回指定位置的颜色。如果 x 或 y 超出范围(分别为宽度或高度的负数或 >=),则引发异常。

这就是 Bitmap.getPixel() 的引用;

您需要做什么才能打印出来,以便人类可读。我用 android 编程过,但没有用 android 做这个。我在我的一个程序中使用了以下函数。

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] + ")";
}

我不知道你到底想做什么,所以上面的代码不会回答你的问题......但应该可以帮助你找到你想要使用像素数据的答案。

希望这会有所帮助! :)

【讨论】:

  • 感谢 Zeveso 的回答。但是,我不是要获取 RGB 值,而是要获取像素的单个灰度值。我有单通道的 PNG,每像素 16 位。在该像素中,有一个介于 0 和 2^16-1 (65535) 之间的高度值。
猜你喜欢
  • 2014-08-25
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 2013-10-12
  • 2015-08-04
  • 2015-12-13
  • 1970-01-01
  • 2014-07-27
相关资源
最近更新 更多