camera2 api将yuv420转换为rgb green out

mr.*_*leo 8 android image yuv android-camera

我尝试将图像从YUV_420_888转换为rgb,我对输出图像有些麻烦.在ImageReader中,我以YUV_420_888格式获取图像(使用相机2 api获取此图像预览).

imageReader = ImageReader.newInstance(1920,1080,ImageFormat.YUV_420_888,10);
Run Code Online (Sandbox Code Playgroud)

在android sdk中为YuvImage类编写,即YuvImage仅使用NV21,YUY2.

因为我们可以看到N21和yuv420之间的差异不大,我尝试将数据转换为N21

YUV420: 在此输入图像描述

N21: 在此输入图像描述

onImageAvailable中我单独获得每个Planes并将它们放在正确的位置(如图像所示)

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

ByteBuffer bufferY = image.getPlanes()[0].getBuffer();
byte[] data0 = new byte[bufferY.remaining()];
bufferY.get(data0);

ByteBuffer bufferU = image.getPlanes()[1].getBuffer();
byte[] data1 = new byte[bufferU.remaining()];
bufferU.get(data1);

ByteBuffer bufferV = image.getPlanes()[2].getBuffer();
byte[] data2 = new byte[bufferV.remaining()];
bufferV.get(data2);
...
outputStream.write(data0);
for (int i=0;i<bufferV.remaining();i++) {
    outputStream.write(data1[i]);
    outputStream.write(data2[i]);
}
Run Code Online (Sandbox Code Playgroud)

创建YuvImage后,转换为Bitmap,查看并保存

final YuvImage yuvImage = new YuvImage(outputStream.toByteArray(), ImageFormat.NV21, 1920,1080, null);
ByteArrayOutputStream outBitmap = new ByteArrayOutputStream();

yuvImage.compressToJpeg(new Rect(0, 0,1920, 1080), 95, outBitmap);

byte[] imageBytes = outBitmap.toByteArray();

final Bitmap imageBitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
mImageView.setImageBitmap(imageBitmap);
...
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 95, out);
Run Code Online (Sandbox Code Playgroud)

但我保存的图像是绿色和粉红色的: 捕获图像 捕获图像

我错过了什么??

Ale*_*ohn 2

bufferV.get(data2)增加 ByteBuffer 的位置。这就是循环for (int i=0;i<bufferV.remaining();i++)产生 0 次迭代的原因。您可以轻松地将其重写为

for (int i=0; i<data1.length; i++) {
    outputStream.write(data1[i]);
    outputStream.write(data2[i]);
}
Run Code Online (Sandbox Code Playgroud)