在之前的文章中讲述了如何使用Camera2拍摄RAW图并保存为DNG文件 Android 手机如何拍摄RAW图,本文主要通过源码分析一下DngCreator写文件的基本过程和如何读取DNG文件
什么是DNG文件
DNG(Digital Negative)是Adobe为了统一不同相机厂商raw格式而推出的一种开放的raw image file format,它并不是一种全新的format,而是基于TIFF6.0进行了扩展,包含了EXIF和XMP信息。DNG遵循所有TIFF6.0的格式规则,所以把文件后缀名dng改为tif/tiff后都是可以直接预览图片的
用mac自带的预览工具查看DNG文件时可以看到dng文件是不支持直接编辑的
什么是TIFF文件
TIFF(Tagged Image File Format)文件以tif或tiff为扩展名,数据格式为一种3级体系结构,分为:文件头信息区,标识信息区和图像数据区
TIFF的可扩展性非常强,如jpeg,lossless jpeg和任意数据宽度的原始无压缩数据都可以方便的嵌入到TIFF中去,所以在数字影像,遥感和医学等领域都获得了广泛的应用
DngCreator源码分析
// mCharacteristics:当前CameraDevice静态属性的描述
// mCaptureResult:当前拍照帧携带的3A,flash等信息的集合
// mImage:封装了当前拍照帧的buffer
// step1:
// DngCreator类加载的时候会调用nativeClassInit方法初始化一些依赖的jni对象
// step2:
// new DngCreator实例的时候调用nativeInit生成NativeContext对象
DngCreator dngCreator = new DngCreator(mCharacteristics, mCaptureResult);
FileOutputStream output = null;
try {
output = new FileOutputStream(mFile);
// step3:
// 调用到nativeWriteImage,内部会通过TiffWriter来写IFH/IFD/DE
dngCreator.writeImage(output, mImage);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
closeOutput(output);
}
// step4:
// dngCreator对象在GC回收的时候会调用nativeDestroy释放NativeContext
frameworks/base/core/jni/android_hardware_camera2_DngCreator.cpp
DngCreator类加载的时候准备依赖的一些jni对象
初始化DngCreator实例的时候,准备NativeContext
Java层调用writeImage方法时,内部主要分为两个步骤
第一步是生成TiffWriter来写IFH和IFD
TiffWriter如何写IFH和IFD的具体过程可以参考源码
frameworks/av/media/img_utils/src/TiffWriter.cpp
第二步是填充buffer数据
DngCreator对象释放的时候主要是释放底层的NativeContext资源
如何读取DNG文件
当我们读取jpg/jpeg/png文件时,可以通过BitmapFactory#decodeStream接口,对于DNG文件该接口也是适用的
参考
1.【DNG格式解析】
https://www.cnblogs.com/adong7639/p/4446828.html
2.【TIFF图像文件格式详解】
https://www.cnblogs.com/MetaWang/p/10024243.html
3.【DNG Specification】
https://helpx.adobe.com/content/dam/help/en/photoshop/pdf/dng_spec_1_6_0_0.pdf
4.【AndroidXRef Pie9.0.0_r3】
http://androidxref.com/9.0.0_r3/xref