Java Android 16位彩色图像到位图
我正试图从一个嵌入式摄像头获得一个分辨率为80 x 60的16位彩色图像()。我成功地从相机中获取9600(80*60*16/8)字节,但在显示图像时遇到问题。我使用以下代码将字节数组转换为位图:Java Android 16位彩色图像到位图,java,android,bitmap,rgb,16-bit,Java,Android,Bitmap,Rgb,16 Bit,我正试图从一个嵌入式摄像头获得一个分辨率为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字节 现在,我得到的图像如下所
bm = Bitmap.createBitmap(80, 60, Bitmap.Config.RGB_565);
bm.copyPixelsFromBuffer(ByteBuffer.wrap(jpegBytes));
jpegBytes是图像字节的数组,长度为9600字节
现在,我得到的图像如下所示:
99%的时间。但是,我可以获得如下未损坏的图像:
很少。有人对为什么会发生这种情况有什么建议吗?非常感谢
更新:
看起来所有像素都在正确的位置,但它们的RGB值混淆了。例如,两张照片之间的白色部分是相同的,因为RGB的顺序与变白无关。但是,很明显,颜色混淆了,因为红色的椅子在损坏的图像中显示为蓝色,而蓝色的背包在损坏的图像中显示为绿色 从以下文件: 每个像素存储在2个字节上,仅对RGB通道进行编码: 红色以5位精度(32个可能值)存储,绿色为 以6位精度(64个可能值)存储,蓝色为 以5位精度存储此配置可能会产生轻微的 可视工件取决于源的配置。 例如,如果不抖动,结果可能显示绿色。到 为了获得更好的结果,应采用抖动。此配置可能会 在使用不需要高颜色的不透明位图时非常有用 忠诚
我遇到了一个类似的问题,我就是这样解决的: (1) 检查您收到的字节数组,查看是否需要先将其反转,然后再将其包装到ByteBuffer中 (2) 检查ByteBuffer endianness,查看是否需要将其更改为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++;
}
}
byte[]图像数据;(接收到字节数组)
反向字节数组(imageData);
位图Bitmap=Bitmap.createBitmap(imgWidth、imgHeight、Bitmap.Config.RGB_565);
ByteBuffer缓冲区=ByteBuffer.wrap(图像数据);
ByteBuffer newBuffer=ByteBuffer.allocate(buffer.capacity());
newBuffer.order(ByteOrder.LITTLE_ENDIAN);
对于(int i=0;ii){
tmp=阵列[j];
数组[j]=数组[i];
数组[i]=tmp;
j--;
i++;
}
}
看起来图像结构正确,但颜色不正确。您确定图像始终应为RGB_565格式吗?此外,您是否确定图像数据是原始像素(而不是jpeg编码)?根据相机的数据表,图像应以RGB_565格式传输。我能够从相机中获取4位和8位灰度图像,并使用ARGB_8888显示它们,但当我使用ARGB_8888显示16位图像时,应用程序崩溃。这是因为在16位图像中,每个像素有2个字节,而不是ARGB_8888需要的每个像素4个字节。这可能是字节顺序问题。如果使用bm.copyPixelsFromBuffer(ByteBuffer.wrap(jpegBytes.order)(ByteOrder.LITTLE_ENDIAN)),会发生什么代码>?我尝试了Little Endian和Big Endian,但仍然得到了相同的错误图片。似乎所有像素都在正确的位置,但它们的RGB值混淆了。例如,两张照片之间的白色部分是相同的,因为RGB的顺序与变白无关。但是,很明显,这些颜色是混合的,因为红色的椅子在损坏的图像中显示为蓝色,而蓝色的背包在损坏的图像中显示为绿色。除非缓冲区中的数据是ARGB_8888格式(OP说不是),这根本不起作用。根据相机的第8页,16位彩色图像是作为原始565(RGB)图像传输的,因此Android的RGB_565理论上应该可以工作。