我正在测试新的Camera2 API,我能够以YUV_420_888
格式捕捉相机预览。我接下来要做的是将这些数据提供给图像处理库,该库接受byte[]
参数。
我找到了converting YUV_420_888
to RGB之类的示例,但我仍然需要将生成的位图转换为byte[]
到ByteArrayOutputStream
,经过实验,这会大大减慢应用程序的速度。
我的问题是,如何有效地将YUV_420_888
转换为byte[]
?
答案 0 :(得分:0)
图像处理库需要的byte []数组的实际格式是什么?是RGB吗? YUV平面? YUV半米兰?
假设它是RGB,假设您引用将YUV_420_888转换为RGB,则可以修改该示例以不从分配中创建位图 - 只需使用带有byte []而不是Bitmap的Allocation.copyTo。
答案 1 :(得分:0)
我花了很多时间来寻找解决方案,所以我找到了它,从另一个关于stackoverflow的人的答案中,我想分享我的自定义代码,该代码针对循环号进行了优化,可与我一起使用,适用于YUV420 camera2 API的图像:D
public static byte[] imageToMat(Image image) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer0 = planes[0].getBuffer();
ByteBuffer buffer1 = planes[1].getBuffer();
ByteBuffer buffer2 = planes[2].getBuffer();
int offset = 0;
int width = image.getWidth();
int height = image.getHeight();
byte[] data = new byte[image.getWidth() * image.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8];
byte[] rowData1 = new byte[planes[1].getRowStride()];
byte[] rowData2 = new byte[planes[2].getRowStride()];
int bytesPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8;
// loop via rows of u/v channels
int offsetY = 0;
int sizeY = width * height * bytesPerPixel;
int sizeUV = (width * height * bytesPerPixel) / 4;
for (int row = 0; row < height ; row++) {
// fill data for Y channel, two row
{
int length = bytesPerPixel * width;
buffer0.get(data, offsetY, length);
if ( height - row != 1)
buffer0.position(buffer0.position() + planes[0].getRowStride() - length);
offsetY += length;
}
if (row >= height/2)
continue;
{
int uvlength = planes[1].getRowStride();
if ( (height / 2 - row) == 1 ) {
uvlength = width / 2 - planes[1].getPixelStride() + 1;
}
buffer1.get(rowData1, 0, uvlength);
buffer2.get(rowData2, 0, uvlength);
// fill data for u/v channels
for (int col = 0; col < width / 2; ++col) {
// u channel
data[sizeY + (row * width)/2 + col] = rowData1[col * planes[1].getPixelStride()];
// v channel
data[sizeY + sizeUV + (row * width)/2 + col] = rowData2[col * planes[2].getPixelStride()];
}
}
}
return data;
}