我正在使用 Libraw 读取 RAW 文件(通常是 NEF 格式),一切似乎都很好。经过一些处理,我需要将 RAW 图像保存为 DNG 文件。但是,当我用 Photoshop 打开 DNG 文件时,颜色似乎不对。
为了找到 CFA 模式,我使用 RawProcessor.COLOR 查看模式的前两行和两列。我得到以下模式:\00\01\01\02。然后我将原始图像写入文件:
const int width = RawProcessor.imgdata.sizes.raw_width;
const int height = RawProcessor.imgdata.sizes.raw_height;
const std::array<float, 9> color_matrix = {
raw_color.cam_xyz[0][0], raw_color.cam_xyz[0][1], raw_color.cam_xyz[0][2],
raw_color.cam_xyz[1][0], raw_color.cam_xyz[1][1], raw_color.cam_xyz[1][2],
raw_color.cam_xyz[2][0], raw_color.cam_xyz[2][1], raw_color.cam_xyz[2][2],
};
const std::array<float, 3> as_shot_neutral = {
1.0f / (raw_color.cam_mul[0] / raw_color.cam_mul[1]),
1.f,
1.0f / (raw_color.cam_mul[2] / raw_color.cam_mul[1])
};
const auto base_black_level = static_cast<float>(raw_color.black);
std::array<float, 4> black_level = {
base_black_level + static_cast<float>(raw_color.cblack[0]),
base_black_level + static_cast<float>(raw_color.cblack[1]),
base_black_level + static_cast<float>(raw_color.cblack[2]),
base_black_level + static_cast<float>(raw_color.cblack[3])
};
if (raw_color.cblack[4] == 2 && raw_color.cblack[5] == 2) {
for (int x = 0; x < raw_color.cblack[4]; ++x) {
for (int y = 0; y < raw_color.cblack[5]; ++y) {
const auto index = y * 2 + x;
black_level[index] = raw_color.cblack[6 + index];
}
}
}
static const uint32_t white_level = raw_color.maximum;
static const short bayerPatternDimensions[] = { 2, 2 };
TIFF* tif = TIFFOpen(strAddr.c_str(), "w");
TIFFSetField(tif, TIFFTAG_DNGVERSION, "\01\01\00\00");
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
TIFFSetField(tif, TIFFTAG_CFAREPEATPATTERNDIM, bayerPatternDimensions);
TIFFSetField(tif, TIFFTAG_CFAPATTERN, 4, "\00\01\01\02");
TIFFSetField(tif, TIFFTAG_MAKE, "DNG");
TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, "DNG");
TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, &color_matrix );
TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, &as_shot_neutral );
TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 4, &black_level);
TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &white_level);
for (int i = 0; i < height; i++)
TIFFWriteScanline(tif, &RawProcessor.imgdata.rawdata.raw_image[(i)*width], i, 0);
TIFFWriteDirectory(tif);
TIFFClose(tif);
我使用以下方法找到 cam_xyz:RawProcessor.imgdata.color.cam_xyz,它是一个 4x3 矩阵,我删除了最后一行以获得 cam_xyz。cam_mul 来自 RawProcessor.imgdata.color.cam_mul,它有 4 个元素,我删除了最后一个元素以获得 cam_mul。cam_mul 的值在传递给 Tiff 标记之前被反转。
编辑:这是使用 LibRaw 从文件中读取 RAW 图像的代码:
LibRaw RawProcessor;
int ret;
if ((ret = RawProcessor.open_file(strAddr.c_str())) != LIBRAW_SUCCESS)
return false;
// Unpack the image
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
return false;
// Data unpacking
ret = RawProcessor.dcraw_process();
if (LIBRAW_SUCCESS != ret) // error at the previous step
return false;
else // Successful document processing
{
std::cout << "Successful document processing..." << std::endl;
// Process the RAW data
}
我得到 cam_xyz 的以下值:
[1.0405 -0.3755 -0.127
-0.5461 1.3787 0.1793
-0.104 0.2015 0.6785
0 0 0]
和 cam_mul : [1.78906, 1, 1.67969, 1]。
正如我所说,我有一个大问题,即当我在 Photoshop 中加载 DNG 图像时,颜色不正确,这可能是由于颜色矩阵或白平衡造成的。
另一个问题是,当我在 Photoshop 中加载原始 NEF 文件时,大小为 5504x8256,而 DNG 文件的大小为 5520x8288。我也检查了这些值:
RawProcessor.imgdata.sizes.top_margin:0
RawProcessor.imgdata.sizes.left_margin:2
这与我在另一个软件中打开 NEF 文件的大小不对应。知道问题出在哪里吗?
尝试此图库中的任何图像 ( https://www.photographyblog.com/previews/nikon_d850_photos ) 将得到与此类似的结果,其中原始 RAW 图像是底部图像,顶部图像是转换后的 DNG 图像: