【发布时间】:2015-04-11 00:17:43
【问题描述】:
API 21 中的 Camera2 中的 Camera.PreviewCallback 是否有任何等效项,比映射到 SurfaceTexture 并拉取 Bitmap 更好?我需要能够将预览数据从相机中提取为 YUV?
【问题讨论】:
标签: android android-camera android-5.0-lollipop yuv android-hardware
API 21 中的 Camera2 中的 Camera.PreviewCallback 是否有任何等效项,比映射到 SurfaceTexture 并拉取 Bitmap 更好?我需要能够将预览数据从相机中提取为 YUV?
【问题讨论】:
标签: android android-camera android-5.0-lollipop yuv android-hardware
您可以从 Google 的 Camera2Basic 示例代码开始。
您需要将ImageReader 的表面作为目标添加到预览捕获请求中:
//set up a CaptureRequest.Builder with the output Surface
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
之后,您可以在ImageReader.OnImageAvailableListener中检索图像:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
if (image != null) {
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
Bitmap bitmap = fromByteBuffer(buffer);
image.close();
}
} catch (Exception e) {
Log.w(LOG_TAG, e.getMessage());
}
}
};
从ByteBuffer 获取Bitmap:
Bitmap fromByteBuffer(ByteBuffer buffer) {
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes, 0, bytes.length);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
【讨论】:
是的,使用ImageReader 类。
使用 ImageFormat.YUV_420_888 格式和您想要的尺寸创建一个 ImageReader(确保您选择的尺寸受您使用的相机设备支持)。
然后使用 ImageReader.getSurface() 将 Surface 与其他预览输出(如果有)一起提供给 CameraDevice.createCaptureSession()。
最后,在您的重复捕获请求中,将 ImageReader 提供的表面添加为目标,然后再将其设置为捕获会话中的重复请求。
【讨论】: