【问题标题】:Camera.PreviewCallback equivalent in Camera2 APICamera2 API 中的 Camera.PreviewCallback 等效项
【发布时间】:2015-04-11 00:17:43
【问题描述】:

API 21 中的 Camera2 中的 Camera.PreviewCallback 是否有任何等效项,比映射到 SurfaceTexture 并拉取 Bitmap 更好?我需要能够将预览数据从相机中提取为 YUV?

【问题讨论】:

    标签: android android-camera android-5.0-lollipop yuv android-hardware


    【解决方案1】:

    您可以从 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);
    }
    

    【讨论】:

    • 它冻结了 Textureview。 (mPreviewRequestBuilder.addTarget(mImageReader.getSurface());)
    【解决方案2】:

    是的,使用ImageReader 类。

    使用 ImageFormat.YUV_420_888 格式和您想要的尺寸创建一个 ImageReader(确保您选择的尺寸受您使用的相机设备支持)。

    然后使用 ImageReader.getSurface() 将 Surface 与其他预览输出(如果有)一起提供给 CameraDevice.createCaptureSession()。

    最后,在您的重复捕获请求中,将 ImageReader 提供的表面添加为目标,然后再将其设置为捕获会话中的重复请求。

    【讨论】:

    • @ Eddy Talvala,当我添加像 mPreviewRequestBuilder.addTarget(mImageReader.getSurface()); 这样的目标时它冻结了表面。
    • 您在 logcat 中遇到什么错误?您是否将表面添加到您的 createCaptureSession 调用中?
    • 是的,在 createCaptureSession 中设置输出的两个表面。 Logcat 没有显示任何错误。它直接锁定,但从前两天卡住了。
    • logcat :- 等待请求完成时超时。它只向 ImageReader Callback 发送三个请求。
    • 在处理完每个图像后是否调用 image.close()?否则,您将耗尽相机以获取免费缓冲区。
    猜你喜欢
    • 2016-02-02
    • 2020-06-15
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2011-09-17
    • 1970-01-01
    • 2015-05-28
    相关资源
    最近更新 更多