我试图从嵌入式相机(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字节。
现在,我的图像看起来像这样:
99%的时间。但是,我能够获得看起来像这样的未损坏的图像:
很少见。有没有人有任何关于为什么会这样的建议?非常感谢!
更新:
似乎所有像素都在正确的位置,但是它们的RGB值混合在一起。例如,两张照片之间的白色部分是相同的,因为RGB的顺序无关紧要白色。然而,很明显颜色是混合的,因为红色椅子在损坏的图像中显示为蓝色,蓝色背包在损坏的图像中显示为绿色
答案 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++;
}
}