这边文章主要记录下在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。