简体   繁体   中英

Android 16-Bit Color Image to Bitmap

I am trying to get a 16-bit color image that is 80 x 60 resolution from an embedded camera ( datasheet here ). I am successfully able to get 9600 (80 * 60 * 16 / 8) bytes from the camera, but I have a problem displaying the image. I am using the following code to convert the byte array into a Bitmap:

bm = Bitmap.createBitmap(80, 60, Bitmap.Config.RGB_565);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(jpegBytes));

jpegBytes is the array of the image's bytes and it is 9600 bytes long.

Right now, I am getting images that look like this:

图像损坏

99% of the time. However, I am able to get non-corrupted images that look like this:

完好的图像

very rarely. Does anyone have any suggestions as to why this is happening? Thanks so much!

UPDATE:

It seems like all the pixels are in the correct spot, but have their RGB values mixed up. For example, the white portion between both photos is the same because the order of RGB does not matter to get white. However, it is clear that the colors are mixed up because the red chair is showing up as blue in the corrupted image and the blue backpack is showing up as green in the corrupted image

Use Config.ARGB_8888 as bitmap config

From the docs for public static final Bitmap.Config RGB_565 :

Each pixel is stored on 2 bytes and only the RGB channels are encoded: red is stored with 5 bits of precision (32 possible values), green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision. This configuration can produce slight visual artifacts depending on the configuration of the source. For instance, without dithering, the result might show a greenish tint. To get better results dithering should be applied. This configuration may be useful when using opaque bitmaps that do not require high color fidelity.

I was with a similar problem, and this is how I solve it:

(1) Check the byte array you have received , see if you need to reverse it first before wrap it into ByteBuffer

(2) Check the ByteBuffer endianness, see if you need to change it to little endian (the default byte ordering is big endian)

In my case, I have to reverse the byte array first, change the ByteBuffer to little endian, then I can get a correct image.

Pseudocode:

byte[] imageData ;  (byte array received)
reverseByteArray(imageData);

Bitmap bitmap = Bitmap.createBitmap(imgWidth, imgHeight,Bitmap.Config.RGB_565);

ByteBuffer buffer = ByteBuffer.wrap(imageData);
ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity());
newBuffer.order(ByteOrder.LITTLE_ENDIAN);
for (int i = 0; i < buffer.capacity(); i++) {
            byte b = buffer.get(i);
            newBuffer.put(b);
        }
newBuffer.flip();
bitmap.copyPixelsFromBuffer(newBuffer);
setImage(bitmap);

//------
public static void reverseByteArray(byte[] array) {
        if (array == null) {
            return;
        }
        int i = 0;
        int j = array.length - 1;
        byte tmp;
        while (j > i) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
            j--;
            i++;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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