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

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

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

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

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

Android Camera2 获取RAW数据_全栈

好了,回到我们这篇文章的重点。重点介绍Raw数据的获取。相关实现代码,google已经给出了官方的demo(微信公众号底部,回复:raw,可获取完整demo代码。 )本文介绍的内容也是基于官方demo来展开~
如果大家了解或者使用过Camera2获取实时yuv或者拍照jpeg数据,那获取raw,其实流程上都是一样。Camera2上我们需要拿到camera的数据,都是通过ImagerReader来获取。
下面贴下核心代码:
1)创建Raw相关的RawImageReader,以及设置数据available监听;

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设置下去。表示我们需要请求该数据。

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)点击拍照后,在数据回调监听里面,对数据进行保存。

private final ImageReader.OnImageAvailableListener mOnRawImageAvailableListener            = new ImageReader.OnImageAvailableListener() {
        @Override        public void onImageAvailable(ImageReader reader) {            dequeueAndSaveImage(mRawResultQueue, mRawImageReader);        }
    };

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

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

Android Camera2 获取RAW数据_程序员_02

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

Android Camera2 获取RAW数据_Android_03

Android Camera2 获取RAW数据_数据_04