如何从原始图像中获取位图

时间:2011-04-11 19:57:53

标签: android android-image

我正在从网络上读取原始图像。此图像已由图像传感器读取,而不是从文件中读取。

这些是我对图像的了解:
〜高度&宽度
〜总大小(以字节为单位)
~8位灰度
~1字节/像素

我正在尝试将此图像转换为位图以在imageview中显示。

这是我试过的:

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.outHeight = shortHeight; //360
opt.outWidth = shortWidth;//248
imageBitmap = BitmapFactory.decodeByteArray(imageArray, 0, imageSize, opt);

decodeByteArray返回 null ,因为它无法解码我的图像。

我也尝试直接从输入流中读取它,而不是先将其转换为字节数组:

imageBitmap = BitmapFactory.decodeStream(imageInputStream, null, opt);

这也会返回 null

我搜索了这个&其他论坛,却无法找到实现这一目标的方法。

有什么想法吗?

编辑:我应该补充一点,我做的第一件事就是检查流是否实际包含原始图像。我使用其他应用程序`(iPhone / Windows MFC)&他们能够阅读并正确显示图像。我只需要想办法在Java / Android中做到这一点。

4 个答案:

答案 0 :(得分:13)

Android不支持灰度位图。首先,您必须将每个字节扩展为32位ARGB int。 Alpha是0xff,R,G和B字节是源图像的字节像素值的副本。然后在该数组的顶部创建位图。

另外(见注释),似乎设备认为0是白色,1是黑色 - 我们必须反转源位。

因此,我们假设源图像位于名为Src的字节数组中。这是代码:

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] = 0xff; // 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));

答案 1 :(得分:1)

我做过类似的事情来解码从相机预览回调中获得的字节流:

    Bitmap.createBitmap(imageBytes, previewWidth, previewHeight, 
                        Bitmap.Config.ARGB_8888);

试一试。

答案 2 :(得分:1)

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] = 0xff; // the alpha.
}

转换循环可能需要花费大量时间将8位图像转换为RGBA,640x800图像可能需要超过500ms ...更快的解决方案是使用ALPHA8格式的位图并使用滤色器:< / p>

//setup color filter to inverse alpha, in my case it was needed
float[] mx = new float[]{
    1.0f, 0, 0, 0, 0, //red
    0, 1.0f, 0, 0, 0, //green
    0, 0, 1.0f, 0, 0, //blue
    0, 0, 0, -1.0f, 255 //alpha
};

ColorMatrixColorFilter cf = new ColorMatrixColorFilter(mx);
imageView.setColorFilter(cf);

// after set only the alpha channel of the image, it should be a lot faster without the conversion step

Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(src));  //src is not modified, it's just an 8bit grayscale array
imageview.setImageBitmap(bm);

答案 3 :(得分:0)

从流中使用Drawable创建。以下是使用HttpResponse的方法,但无论如何都可以获得输入流。

  InputStream stream = response.getEntity().getContent();

  Drawable drawable = Drawable.createFromStream(stream, "Get Full Image Task");