Android 16位彩色图像到位图

时间:2013-07-23 19:32:55

标签: java android bitmap rgb 16-bit

我试图从嵌入式相机(datasheet here)获得一个80 x 60分辨率的16位彩色图像。我成功地从相机中获得了9600(80 * 60 * 16/8)字节,但是显示图像时出现问题。我使用以下代码将字节数组转换为位图:

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

jpegBytes是图像字节的数组,长度为9600字节。

现在,我的图像看起来像这样:

corrupted image

99%的时间。但是,我能够获得看起来像这样的未损坏的图像:

uncorrupted image

很少见。有没有人有任何关于为什么会这样的建议?非常感谢!

更新:

似乎所有像素都在正确的位置,但是它们的RGB值混合在一起。例如,两张照片之间的白色部分是相同的,因为RGB的顺序无关紧要白色。然而,很明显颜色是混合的,因为红色椅子在损坏的图像中显示为蓝色,蓝色背包在损坏的图像中显示为绿色

2 个答案:

答案 0 :(得分:1)

使用Config.ARGB_8888作为位图配置

来自public static final Bitmap.Config RGB_565的文档:

  

每个像素存储在2个字节上,只有RGB通道被编码:   红色以5位精度存储(32个可能的值),绿色是   存储有6位精度(64个可能的值),蓝色是   以5位精度存储。 这种配置可以产生轻微的影响   视觉工件取决于源的配置。 For   例如,没有抖动,结果可能会显示绿色。至   得到更好的结果应该应用抖动。这种配置可能   在使用不需要高颜色的不透明位图时非常有用   保真度。

答案 1 :(得分:0)

我遇到了类似的问题,这就是我解决问题的方法:

(1)检查您收到的字节数组,看看是否需要先将其反转,然后再将其包装到ByteBuffer中

(2)检查ByteBuffer字节顺序,查看是否需要将其更改为little endian(默认字节顺序为big endian)

在我的情况下,我必须首先反转字节数组,将ByteBuffer更改为little endian,然后我才能得到正确的图像。

伪代码:

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++;
        }
    }