开发者

How to get a Bitmap from a raw image

I am reading a raw image from the network. This image has been read by an image sensor, not from a file.

These are the things I know about the image:

~ Height & Width

~ Total size (in bytes)

~ 8-bit grayscale

~ 1 byte/pixel

I'm trying to convert this image to a bitmap to display in an imageview.

Here's what I tried:

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

decodeByteArray returns null, since it cannot decode my image.

I also tried reading it directly from the input stream, without converting it to a Byte Array first:

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

This returns null as well.

I've searched on this & other forums, but cannot find a way to achieve this.

Any ideas?

EDIT: I should add 开发者_JAVA百科that the first thing I did was to check if the stream actually contains the raw image. I did this using other applications `(iPhone/Windows MFC) & they are able to read it and display the image correctly. I just need to figure out a way to do this in Java/Android.


Android does not support grayscale bitmaps. So first thing, you have to extend every byte to a 32-bit ARGB int. Alpha is 0xff, and R, G and B bytes are copies of the source image's byte pixel value. Then create the bitmap on top of that array.

Also (see comments), it seems that the device thinks that 0 is white, 1 is black - we have to invert the source bits.

So, let's assume that the source image is in the byte array called Src. Here's the code:

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));


Once I did something like this to decode the byte stream obtained from camera preview callback:

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

Give it a try.


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

The conversion loop can take a lot of time to convert the 8 bit image to RGBA, a 640x800 image can take more than 500ms... A quicker solution is to use ALPHA8 format for the bitmap and use a color filter:

//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);


Use Drawable create from stream. Here's how to do it with an HttpResponse, but you can get the inputstream anyway you want.

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

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜