我使用RenderScript和Allocation从Android Camera2 API获取YUV_420_888帧,但是一旦我从分配中复制byte [],我只从组成帧的3个平面接收Y平面,而字节[]中的U和V平面值设置为0。我试图模仿previos相机API中的onPreviewframe,以便在应用程序处理相机帧时执行。我的分配创建如下:
Type.Builder yuvTypeBuilderIn = new Type.Builder(rs, Element.YUV(rs));
yuvTypeBuilderIn.setX(dimensions.getWidth());
yuvTypeBuilderIn.setY(dimensions.getHeight());
yuvTypeBuilderIn.setYuvFormat(ImageFormat.YUV_420_888);
allocation = Allocation.createTyped(rs, yuvTypeBuilderIn.create(),
Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);
虽然我的脚本看起来像:
#pragma version(1)
#pragma rs java_package_name(my_package)
#pragma rs_fp_relaxed
rs_allocation my_frame;
答案 0 :(得分:6)
Android示例应用程序HdrViewfinderDemo使用RenderScript处理来自camera2的YUV数据。
https://github.com/googlesamples/android-HdrViewfinder
具体来说,ViewfinderProcessor设置了分配,hdr_merge.rs从中读取。
答案 1 :(得分:3)
是的我做到了,因为我找不到任何有用的东西。但我没有采用建议的方式来定义表面的分配。相反,我只是将三个图像平面的输出转换为RGB。这种方法的原因是我使用YUV420_888数据两倍。首先在高频基础上仅强度值(Y)。其次,我也需要制作一些彩色位图。因此,以下解决方案。 1280x720 YUV_420_888图像的脚本大约需要80ms,可能不是超快,但我的目的还可以。
更新:我在这里删除了代码,因为我在这里写了一个更通用的解决方案YUV_420_888 -> Bitmap conversion,它也考虑了pixelStride和rowStride。
答案 2 :(得分:2)
我认为您可以使用ImageReader将相机的帧渲染到YUV_420_888
reader = ImageReader.newInstance(previewSize.getWidth(), previewSize.getHeight(), ImageFormat.YUV_420_888, 2);
然后将OnImageAvailableListener设置为阅读器:
reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
int jump = 4; //Le nombre d'image à sauter avant d'en traiter une, pour liberer de la mémoire
Image readImage = reader.acquireNextImage();
readImage.getPlane[0] // The Y plane
readImage.getPlane[1] //The U plane
readImage.getPlane[2] //The V plane
readImage.close();
}
}, null);
希望能帮到你
答案 3 :(得分:0)
我在答案中使用的方法与widea几乎相同。
大约50帧之后你得到的例外可能是因为你使用acquireNextImage处理所有帧。文档建议:
警告:请考虑使用acquireLatestImage(),因为它会自动释放较旧的图像,并允许较慢运行的处理例程赶上最新的帧。 [..]
因此,如果您的异常是IllegalStateException,切换到acquireLatestImage可能会有所帮助。
并确保对从ImageReader检索到的所有图像调用close()。