在前面我们已经知道createCaptureSession方法的第一个参数会传入一个list,一般这个list会有三个值,用于preview的SurfaceView的surface,用于保存拍照数据的ImageReader的surface,和缩略图的surface。如果是录像模式,ImageReader的surface就替换为MediaRecoder的surface。
但是在实际开发中,我们经常需要输出YUV数据,这个数据要如何得到呢。
一、Preview的YUV数据
对于Preview而言,输出YUV数据其实非常简单,关键就在于addTarget方法。
mPreviewRequestBuilder!!.addTarget(surface)
一般在预览时,我们会把SurfaceView的surface作为参数传入该方法。当需要输出YUV数据的时候,我们同样把ImagerReader的surface也addTarget就可以了。
具体的步骤如下:
- 配置ImageReader
mImageReader = ImageReader.newInstance(largest.width, largest.height, ImageFormat. YUV_420_888, 2)
mImageReader!!.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler)
- 设置对YUV数据处理
private val mOnImageAvailableListener = ImageReader.OnImageAvailableListener { reader ->
mBackgroundHandler!!.post(
do something…
) })}
- 构建CaptureBuilder,添加target
mPreviewRequestBuilder = mCameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
mPreviewRequestBuilder!!.addTarget(surface)
mPreviewRequestBuilder!!.addTarget(mImageReader!!.surface)
至此就可以在回调中处理获取的YUV数据了。
通过reader.acquireLatestImage()方法得到Image
val width = mImage.width
val height = mImage.height
// YUV420 大小总是 width * height * 3 / 2
val mYuvBytes = ByteArray(width * height * 3 / 2)
// YUV_420_888
val planes: Array<Image.Plane> = mImage.planes
到这里就已经得到了YUV数据,之后就是根据具体的业务逻辑来实现需要的功能了,例如保存YUV文件等。
二、Capture的YUV输出
在调用capture方法时,一般都会进行如下设置:
val captureBuilder = mCameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)
captureBuilder.addTarget(mImageReader!!.surface)
所以只要ImageReader的Format是YUV就可以在回调中获得YUV数据。在这一点上prview和capture对yuv数据的获取没有本质的区别。