2

我正在尝试从嵌入式相机(此处的数据表)获取分辨率为 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 字节。

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

损坏的图像

99% 的时间。但是,我能够获得如下所示的未损坏图像:

未损坏的图像

非常稀有。有人对为什么会发生这种情况有任何建议吗?非常感谢!

更新:

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

4

2 回答 2

1

用作Config.ARGB_8888位图配置

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

每个像素存储在 2 个字节上,仅对 RGB 通道进行编码:红色以 5 位精度存储(32 个可能值),绿色以 6 位精度存储(64 个可能值),蓝色以 5 位精度存储精确。此配置可能会产生轻微的视觉伪影,具体取决于源的配置。例如,如果没有抖动,结果可能会显示为绿色。为了获得更好的结果,应该应用抖动。当使用不需要高颜色保真度的不透明位图时,此配置可能很有用。

于 2013-07-23T19:38:32.367 回答
0

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

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

(2)检查ByteBuffer字节序,看是否需要改成小字节序(默认字节序为大字节序)

就我而言,我必须先反转字节数组,将 ByteBuffer 更改为小端,然后我才能得到正确的图像。

伪代码:

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++;
        }
    }
于 2017-08-07T10:10:31.763 回答