android camera2 处理每一帧并显示其预览

Posted

技术标签:

【中文标题】android camera2 处理每一帧并显示其预览【英文标题】:android camera2 process each frame and display its preview 【发布时间】:2015-09-22 18:47:29 【问题描述】:

我使用https://github.com/googlesamples/android-Camera2Basic,但尝试修改它,以便在将每个帧绘制到表面视图之前访问它。 我明白了,我应该添加额外的表面(ImageReader.getSurface()),并在这个回调中从中读取帧:

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() 

        @Override
        public void onImageAvailable(ImageReader reader) 

           Log.d("Img", "onImageAvailable");
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
        

    ;

问题是这个回调仅在用户捕获图像时调用,而不是在从相机发送到预览屏幕的每个帧上。

这是我尝试添加的内容:

private void createCameraPreviewSession() 
        try 
            SurfaceTexture texture = mTextureView.getSurfaceTexture();
            assert texture != null;

            // We configure the size of default buffer to be the size of camera preview we want.
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

            // This is the output Surface we need to start preview.
            Surface surface = new Surface(texture);

            // We set up a CaptureRequest.Builder with the output Surface.
            mPreviewRequestBuilder
                    = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);

            // Here, we create a CameraCaptureSession for camera preview.
            mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                    new CameraCaptureSession.StateCallback() 

                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) 
                            // The camera is already closed
                            if (null == mCameraDevice) 
                                return;
                            

                            // When the session is ready, we start displaying the preview.
                            mCaptureSession = cameraCaptureSession;
                            try 
                                // Auto focus should be continuous for camera preview.
                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                                // Flash is automatically enabled when necessary.
                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

                                // Finally, we start displaying the camera preview.
                                mPreviewRequest = mPreviewRequestBuilder.build();
                                mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                        mCaptureCallback, mBackgroundHandler);
                                //mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
                             catch (CameraAccessException e) 
                                e.printStackTrace();
                            
                        

                        @Override
                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) 
                            showToast("Failed");
                        
                    , null
            );

            /**TODO added for capturing aeach frame*/
            // This is the CaptureRequest.Builder that we use to take a picture.
            final CaptureRequest.Builder captureBuilder =
                    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(mImageReader.getSurface());

            // Use the same AE and AF modes as the preview.
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

            /**end added for capture each frame*/


         catch (CameraAccessException e) 
            e.printStackTrace();
        
    

【问题讨论】:

您能否在预览前处理帧? 【参考方案1】:

无需创建CaptureRequest.Builder 的新实例,只需将ImageReaderSurface 添加到mPreviewRequestBuilder 的输出目标即可。

【讨论】:

以上是关于android camera2 处理每一帧并显示其预览的主要内容,如果未能解决你的问题,请参考以下文章

获取每个android.hardware.camera2帧在surfacetexture上显示之前的数据

如何在android studio中获取camera2 api中的每一帧,例如camera api中的PreviewCallback和camerax中的ImageAnalysis.Analyzer?

利用Android Camera2 的照相机api 实现 实时的图像采集与预览

OpenCv - 输出视频未播放

提取视频每一帧保存图片-MATLAB

使用 Android L 和 Camera2 API 处理相机预览图像数据