使用c中的libjpeg在CMYK中保存灰度

时间:2014-04-17 01:10:38

标签: c jpeg grayscale libjpeg cmyk

如果这个函数做了我认为它的功能,似乎在我的机器上至少在CMYK中,C = 0,M = 0,Y = 0和K = 0不对应白色!有什么问题?

float *arr是一个包含size元素的float数组。我希望根据需要将此数组保存为带有IJG的libjpeg的JPEG数据在两个颜色空间中:g:灰度和c:CMYK。我按照他们的示例,使用JSAMPLE *jsr元素的数量生成输入JSAMPLE数组,具体取决于颜色空间:灰度的size元素和CMYK的4*size元素。 JSAMPLE至少是我机器上unsigned char的另一个名称。可以看到完整的程序on Github。这就是我填写jsr

的方式
void
floatfilljsarr(JSAMPLE *jsr, float *arr, size_t size, char color)
{
  size_t i;
  double m;
  float min, max;

  /* Find the minimum and maximum of the array:*/
  fminmax(arr, size, &min, &max);
  m=(double)UCHAR_MAX/((double)max-(double)min);

  if(color=='g')
    {
      for(i=0;i<size;i++)
        jsr[i]=(arr[i]-min)*m;
    }
  else
    for(i=0;i<size;i++)
      {
        jsr[i*4+3]=(arr[i]-min)*m;
        jsr[i*4]=jsr[i*4+1]=jsr[i*4+2]=0;
      }
}

我应该注意,color在此功能之前已被检查为cg。 然后,我将JPEG图像与example.c源中的libjpeg程序完全相同。

以下是在TeX文档中打印两个图像后的输出。灰度位于左侧,CMYK位于右侧。两个图像都是由相同的有序数组组成的,所以左下角的元素(数组中的第一个,我已经定义并在此处显示)的JSAMPLE值为0,右上角元素的JSAMPLE值为255。

grayscale (left) and CMYK (right) comparison.

为什么两张图片不相似?由于性质的不同,我预计CMYK图像会反转,其底部是明亮的,顶部是黑色的。它们显示的JSAMPLE值(灰度中的唯一值和CMYK中的K通道)是相同的,但是我得到的输出不是我预期的! CMYK图像也更亮到顶部,但非常微弱!

似乎C = 0,M = 0,Y = 0和K = 0至少与此算法和我的机器上的白色不对应!?!当我只更换K通道并将其余部分保持为零时,如何设置白色?

2 个答案:

答案 0 :(得分:1)

尝试反转您的K频道:

       jsr[i*4+3]= (m - ((arr[i]-min)*m);

答案 1 :(得分:0)

我想我找到了自己的答案。首先,我尝试将所有四种颜色设置为相同的值。它确实产生了合理的结果,但输出并没有像我预期的那样倒转。使得所有四种颜色中具有最大值的像素是白色而不是黑色!

那时我突然想到在这个过程的某个地方,无论是在IJG的libjpeg还是在JPEG标准中,我都不知道哪个,CMYK颜色是相反的。例如,Cyan值为0实际上在显示器或打印设备上被解释为UCHAR_MAX,反之亦然。如果这是解决方案,那么问题中的图像太暗并且其灰度与灰度图像相同的事实可以很容易地解释(因为我将所有其他三种颜色设置为零,这实际上被解释为最大强度!)。

所以我将前三个CMYK颜色设置为全范围(= UCHAR_MAX):

jsr[i*4]=jsr[i*4+1]=jsr[i*4+2]=UCHAR_MAX /* Was 0 before! */;

然后令我惊讶的是图像有效。灰度(左)灰度阴影较暗,但至少一般都可以解释并且相当类似。我已单独检查并且两者的绝对黑色颜色相同,但对于相同的像素值,灰度的灰度阴影更暗。

On monitor

我在打印(下图)上检查后,结果似乎差别不大,尽管灰度级的灰色阴影更暗!用我的智能手机拍摄的图像!

On paper

另外,在我进行此更改之前,在普通的图像查看器(我正在使用Scientific Linux)上,图像将完全变黑,这就是为什么我认为我看不到CMYK图像!但经过这次修正后,我可以看到CMYK图像就像普通图像一样。事实上使用Eye of GNOME(GNOME中的默认图像查看器),两者几乎看起来完全相同。

相关问题