Android Camera2 获取RAW数据

2023-10-16 21:21:43 浏览数 (1)

这边文章主要记录下在Android系统上,如何通过Camera2 API去拿到RAW数据,也是当个备忘。

平时我们拿实时预览数据,更多的是获取yuv数据。一般涉及到raw域算法在APP层实现的时候,我们才会用到获取raw数据。

APP上集成Raw算法的思路。以拍照为例,基本是这样:APP拿到raw数据,处理完成后,再通过reprocess接口,再次传给hal,然后这个数据会经过平台端isp各个模块处理,最后编码生成的jpeg数据,再回调给上层。

当然,还会有其它使用场景,比如传输raw数据给三方算法,三方算法处理完成后,直接就返回bitmap或者其它数据类型,本地进行保存或者做其它处理等等。

关于reprocess接口的调用,以及应用端Raw域算法的集成,前面在csdn专栏和知识星球也有写过,感兴趣的同学可以去翻翻看看~

CSDN文章链接:https://blog.csdn.net/Mr_ZJC/article/details/129908488?spm=1001.2014.3001.5501

好了,回到我们这篇文章的重点。重点介绍Raw数据的获取。

相关实现代码,google已经给出了官方的demo

本文介绍的内容也是基于官方demo来展开~

如果大家了解或者使用过Camera2获取实时yuv或者拍照jpeg数据,那获取raw,其实流程上都是一样。Camera2上我们需要拿到camera的数据,都是通过ImagerReader来获取。

下面贴下核心代码:

1)创建Raw相关的RawImageReader,以及设置数据available监听;

代码语言:javascript复制
private RefCountedAutoCloseable<ImageReader> mRawImageReader;

 mRawImageReader = new RefCountedAutoCloseable<>(
                                ImageReader.newInstance(largestRaw.getWidth(),
                                        largestRaw.getHeight(), ImageFormat.RAW_SENSOR, /*maxImages*/ 5));
                                        
 mRawImageReader.get().setOnImageAvailableListener(
                            mOnRawImageAvailableListener, mBackgroundHandler);

2) 创建session的时候,把RawImagerReader的surface设置下去。表示我们需要请求该数据。

代码语言:javascript复制
mCameraDevice.createCaptureSession(Arrays.asList(surface,
                            mJpegImageReader.get().getSurface(),
                            mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession cameraCaptureSession) {
                            synchronized (mCameraStateLock) {
                            ......
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
                           ......
                        }
                    }, mBackgroundHandler
            );

3)点击拍照后,在数据回调监听里面,对数据进行保存。

代码语言:javascript复制
 private final ImageReader.OnImageAvailableListener mOnRawImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {

        @Override
        public void onImageAvailable(ImageReader reader) {
            dequeueAndSaveImage(mRawResultQueue, mRawImageReader);
        }

    };

通过上面的代码片段,大家可以看到,其实流程真的是和我们拍照和获取yuv数据是一样的。

这里有个疑问点,相信有不少同学也有 同样的疑惑。初始化ImageReader的时候,RAW相关的格式,光是从名字上看,就有4个,应该选择用哪个呢,它们之间又有什么区别呢。

如下图所示,RAW10和RAW12,是和bit位数相关。Google官方demo,选择的格式是RAW_SENSOR。

0 人点赞