lcms2通过C中的配置文件将CMYK转换为RGB - 输入/输出值的帮助

时间:2014-03-21 14:10:01

标签: c rgb icc cmyk

我正在尝试使用lcms2 lib通过icc配置文件将CMYK转换为RGB。 我在http://www.littlecms.com/1/TUTORIAL.TXT上找到了一些示例代码 - >示例1:如何将RGB转换为CMYK并返回 但是,如果我在我的代码中使用两个给定的配置文件,我收到的结果值接近0。 我的代码是:

cmsHPROFILE hInProfile, hOutProfile;
cmsHTRANSFORM hTransform;
int i;

hInProfile  = cmsOpenProfileFromFile("/Users/me/Downloads/ECI_Offset_2009/ISOcoated_v2_300_eci.icc", "r");
hOutProfile = cmsOpenProfileFromFile("/Users/me/Downloads/profiles/sRGB Color Space Profile.ICM", "r");

hTransform = cmsCreateTransform(hInProfile,
                                TYPE_CMYK_8,
                                hOutProfile,
                                TYPE_RGB_8,
                                INTENT_PERCEPTUAL, 0);

for (uint j = 0; j < cinfo.output_height; ++j) {
    uchar *in = outImage->scanLine(j) + cinfo.output_width * 4;
    QRgb *out = (QRgb*)outImage->scanLine(j);

    for (uint i = cinfo.output_width; i--; ) {
        double k = in[3]/255.0;
        double cmy[3] = {in[0]/255.0 , in[1]/255.0 , in[2]/255.0 };//scale to 0.0...1.0
        double rgb[3];
        cmsDoTransform(hTransform, cmy, &rgb, 1);
        qDebug() << cmy[0] << cmy[1] << cmy[2] << "|" << rgb[0] << rgb[1] << rgb[2];
        out[i] = qRgb(rgb[0]*255, rgb[1]*255, rgb[2]*255);
    }
}

cmsDeleteTransform(hTransform);
cmsCloseProfile(hInProfile);
cmsCloseProfile(hOutProfile);

我得到的输出是(来自qDebug行):

...
0.356863 0.196078 0.345098 | 2.1432e-299 1.35934e-312 -1.81433e-196 
0.490196 0.294118 0.482353 | 2.1432e-299 1.35934e-312 -1.81433e-196 
0.537255 0.258824 0.466667 | 2.1432e-299 1.35934e-312 -1.81433e-196 
0.419608 0.227451 0.364706 | 2.1432e-299 1.35934e-312 -1.81433e-196 
0.34902 0.305882 0.345098 | 2.1432e-299 1.35934e-312 -1.81433e-196 
0.14902 0.133333 0.0980392 | 2.1432e-299 1.35934e-312 -1.81433e-196
...

我做错了什么?应该找到icc配置文件。如果我错误的路径 进入功能,应用程序崩溃了,那么问题出在哪里呢? 非常感谢你。

此致 马克西姆

1 个答案:

答案 0 :(得分:2)

这里有一些问题:

  1. 您在创建转换时指定了8位类型(TYPE_CMYK_8TYPE_RGB_8),但是您将双打传递给cmsDoTransform() - cmy和{ {1}}是双数组。您应该将8位数组传递给rgb
  2. 您只是将cmsDoTransform()(3)值传递给CMY,但您应该为每个像素传递cmsDoTransform()(4)个值。 CMYK每个像素有四个组件,因此您需要将每个像素的4个值传递给CMYK
  3. 为每个像素调用cmsDoTransform()效率不高。 LCMS经过优化,可以处理像素阵列,将整个图像或至少每条扫描线传递到cmsDoTransform()会更高效。
  4. 我不确定为什么要按cmsDoTransform()递增in指针。这意味着输入缓冲区用于cinfo.output_width * 4(下一行向下),而输出缓冲区用于outImage->scanLine(j+1)。这有什么理由吗?我在下面的代码中省略了它。

    outImage->scanLine(j)
  5. 我假设您在使用qRgb和qDebug时正在与QImages合作。 QImages通常是每像素32位图像 - ARGB或XRGB(忽略alpha分量)。如果是这种情况,那么在创建转换时,您将需要使用// Why add "cinfo.output_width * 4” here? uchar *in = outImage->scanLine(j) + cinfo.output_width * 4; TYPE_RGBA_8,具体取决于为QImage存储Alpha通道的位置 - LCMS将忽略Alpha通道。

    通过所有这些修改,代码看起来像这样(未经测试):

    TYPE_ARGB_8

    您可以通过直接在QImage的数据缓冲区上操作,在一次调用中完成所有操作:

    hTransform = cmsCreateTransform(hInProfile,
                                    TYPE_CMYK_8,
                                    hOutProfile,
                                    TYPE_ARGB_8,  //  ARGB is most likely for QImage
                                    INTENT_PERCEPTUAL, 0);
    
    for (uint j = 0; j < cinfo.output_height; ++j) {
        uchar *in = outImage->scanLine(j);
        uchar *out = outImage->scanLine(j);
    
        cmsDoTransform(hTransform, in, out, cinfo.output_width);
    }