1

我正在使用 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]。

  1. 正如我所说,我有一个大问题,即当我在 Photoshop 中加载 DNG 图像时,颜色不正确,这可能是由于颜色矩阵或白平衡造成的。

  2. 另一个问题是,当我在 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 图像:

转换后的 DNG 原始RAW

4

0 回答 0