dng格式是数码相机原始数据的公共存档格式,是Adobe创建的一种开源RAW文件格式。DNG文件存储由各种相机型号(如哈苏、宾得和徕卡)捕获的未压缩图像数据。DNG文件可以使用多个图像查看软件打开,包括 Windows和macOS 中的内置照片应用程序。
dng_sdk附带一个dng_validate程序,可以打印所有的tag信息。当然也可以稍微修改做其它用途。

dng_validate命令行
使用-v参数,可以获取很多dng的tag信息,如下图


RAW格式是原始拜耳数据,我们是如何看到彩色的图像了,这里借用Adobe的dng sdk一步一步给大家做个演示。
其实下面的-1 -2 -3其实就是图片转换的3个步骤,下面我们一步一步的来学习。

第一步:从dng文件中把raw数据解析出来
首先-1,看看dng_sd帮助怎么说的,简单来说就是原始数据输出,啥都不干
The “-1” option causes the unprocessed raw image data to be written to the named output file. This applies only to the next input file after the switch.
其对应的dng_sdk源码为:
// Option to write stage 1 image.
if (gDumpStage1.NotEmpty())
{
if (negative->Stage1Image())
{
dng_file_stream stream2(gDumpStage1.Get(), true);
const dng_image& stage1 = *negative->Stage1Image();
dng_image_writer writer;
writer.WriteTIFF(host,
stream2,
stage1,
stage1.Planes() >= 3 ? piRGB
: piBlackIsZero);
}
gDumpStage1.Clear();
}
// Metadata.
negative->SynchronizeMetadata();
使用-1 参数就能保存我们的raw图像数据,可以用ps打开,这里就不演示了。
使用下面的代码也可以保存这个文件
char* p_stage1_buffer = new char[stage1.PixelSize() * stage1.Height() * stage1.Width()];
if (p_stage1_buffer != nullptr)
{
dng_pixel_buffer stage1_pixel_buffer(stage1.Bounds(), 0, stage1.Planes(), stage1.PixelType(), pcPlanar, p_stage1_buffer);
stage1.Get(stage1_pixel_buffer);
FILE* stage1_f = fopen("stage1.raw", "w+b");
if (stage1_f != nullptr)
{
fwrite(p_stage1_buffer, stage1.PixelSize(), stage1.Width() * stage1.Height(), stage1_f);
fclose(stage1_f);
}
delete[] p_stage1_buffer;
}
第二步:黑电平校准
从第一步可知,这个raw是BGGR的拜耳格式,1个拜耳通道的black level 都是 528, white level = 4095。也就是说,这个raw的是12bit的,因此最大值为 (1<<12)-1 = 4095。

我们看下-2 帮助文档怎么解释的:
The “-2” option causes the image data after linearization and black/white level mapping to be written to the named output file. This applies only to the next input file after the switch.
下面是代码,首先根据pixel位置和拜耳格式,获取当前pixel是哪种类型,是R/G/G/B四种类型的哪一种,然后再分别减去对应的black level值;减完black level以后,值域范围变成了0~3839,我们需要把它映射回0~4095,因此,所有的pixel都乘上了一个global_gain值;
static void blc_correct(UINT16* buf, UINT32 width, UINT32 height, UINT16 white_level, BAYER_TYPE bayer, const UINT16 blc_vec[4])
{
UINT32 global_gain = UINT32(white_level * 1024) / (white_level - blc_vec[0]);
UINT32 size = width * height;
for (UINT32 i = 0; i < height; i++)
{
for (UINT32 j = 0; j < width; j++)
{
PIXEL_TYPE type = get_pixel_type(j, i, bayer);
UINT16 blc_value = blc_vec[type];
INT32 temp = buf[i*width+j] - blc_value;
if (temp < 0)
temp = 0;
else if (temp > white_level)
temp = white_level;
UINT32 out = ((UINT32)temp * global_gain + 512) >> 10;
if (out < 0)
out = 0;
else if (out > white_level)
out = white_level;
buf[i*width + j] = (UINT16)out;
}
}
}
-2 之后会得到一张处理完黑电平之后的一张图像。

第三步:插值,白平衡,gama校准
The “-3” option causes the image data after demosaic processing, but prior to color space conversion, noise reduction, sharpening, etc., to be written to the named output file. This applies only to the next input file after the switch.
- 男女婚外暧昧有哪些具体形式(男女之间,3种互动体现暖昧)
- 男朋友有新欢的征兆(别傻了,他有了新欢,才会这样)
- 初次约会聊怎么不冷场?(避免冷场,几个高效的交流技巧)
- 让人回心转意的话语有哪些(记住三句话,就不会那么难过)
- 女人彻底消失后男人心理变化(如果所有女人从地球消失,男人会如何反应?)
- 男女朋友应该怎么维持感情(男女之间感情再好,也需要六样实力来维持)
- 最能让女孩心动的表白情话(让女人心动的肉麻情话)
- 女人做什么会让男人觉得跟你分开后很后悔(死缠烂打没有用,这样做才是上上策)
- 如何挽回白羊座女生(关于复合的一些小建议)
- 女生提分手怎么挽回让她感动(女生频繁提“分手”导致关系破裂该怎么挽回)