5

我正在从相机中检索原始图像,图像的规格如下:

  • 80 x 60 分辨率
  • 4位灰度

我将图像作为字节数组检索,并有一个 2400 (1/2 * 80 * 60) 字节长的数组。下一步是将字节数组转换为位图。我已经用过

BitmapFactory.decodeByteArray(bytes, 0, bytes.length)

但这并没有返回可显示的图像。我查看了这篇文章并将下面的代码复制到我的 Android 应用程序中,但我得到了“缓冲区不够大,无法容纳像素”运行时错误。

byte [] Src; //Comes from somewhere...
byte [] Bits = new byte[Src.length*4]; //That's where the RGBA array goes.
int i;
for(i=0;i<Src.length;i++)
{
    Bits[i*4] =
        Bits[i*4+1] =
        Bits[i*4+2] = ~Src[i]; //Invert the source bits
    Bits[i*4+3] = -1;//0xff, that's the alpha.
}

//Now put these nice RGBA pixels into a Bitmap object

Bitmap bm = Bitmap.createBitmap(Width, Height, Bitmap.Config.ARGB_8888);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(Bits));

在线程的底部,原始海报与我目前遇到的错误相同。但是,上面粘贴的代码解决了他的问题。有人对我应该如何将原始图像或 RGBA 数组转换为位图有任何建议吗?

非常感谢!

更新:

我遵循了 Geobits 的建议,这是我的新代码

byte[]  seperatedBytes = new byte[jpegBytes.length * 8];
for (int i = 0; i < jpegBytes.length; i++) {
    seperatedBytes[i * 8] = seperatedBytes[i * 8 + 1] = seperatedBytes[i * 8 + 2] = (byte) ((jpegBytes[i] >> 4) & (byte) 0x0F);
    seperatedBytes[i * 8 + 4] = seperatedBytes[i * 8 + 5] = seperatedBytes[i * 8 + 6] = (byte) (jpegBytes[i] & 0x0F);
    seperatedBytes[i * 8 + 3] = seperatedBytes[i * 8 + 7] = -1; //0xFF
}

现在,我可以使用此命令获取位图

Bitmap bm = BitmapFactory.decodeByteArray(seperatedBytes, 0, seperatedBytes.length);

但位图的大小为 0KB。

我得到的图像是来自这台相机的原始图像。不幸的是,检索预压缩的 JPEG 图像不是一种选择,因为我需要 4 位灰度。

4

2 回答 2

2

如果输入的图像只有 2400 字节,这意味着每个字节有两个像素(每个 4 位)。当ARGB_88882400 * 4 = 9600每个像素需要 4 个字节或60 * 80 * 4 = 19200.

您需要将每个传入字节拆分为一个上/下半字节值,然后将其应用于以下 8 个字节(不包括 alpha)。您可以查看此答案以获取有关如何拆分字节的示例。

基本上:

  • 将传入的字节i分成两个半字节,ia并且ib
  • 通过应用ia到传出字节i*8(i*8)+2
  • 通过应用ib到传出字节(i*8)+4(i*8)+6
  • 字节(i*8)+3(i*8)+7是 alpha ( 0xFF)

一旦你有正确大小的字节缓冲区,你应该可以毫无问题地使用decodeByteArry()

于 2013-07-19T00:20:47.463 回答
1

如果我理解正确,您有一个字节数组,每个字节包含 2 个灰度值。我想说灰度值可以被认为是一个简单的强度值,不是吗?

因此,您需要做的第一件事是将灰度值分成单个字节,因为 BitmapFactory.decodeByteArray 可能无法处理您的“半字节”。这可以通过位操作轻松完成。要获得字节 `0bxxxxxxxx` 值的第一个 4 位,您需要右移 4 次:`0bxxxxxxxx >> 4`,这将导致 `0b0000xxxx`。第二个值可以按位或使用模式“0b00001111”获得:“0b00001111 ^ 0bxxxxxxxx”将导致“0b0000xxxx”。(有关位操作的详细信息,请参见此处:位操作

这两个值现在可以存储到一个新的字节数组中。如果你对每一对半字节都这样做,你会得到一个完整字节的数组,最后会加倍大小。

我不确定这对于“BitmapFactory.decodeByteArray”是否已经足够了,或者您是否必须为每个 RGBA 通道重复每个字节 4 次,这会使您的字节数组的大小再次增加原始大小的四倍. 我希望我没有误解任何东西,我的建议会有所帮助;)

于 2013-07-19T00:20:59.803 回答