【问题标题】:Saving grayscale in CMYK using libjpeg in c在 C 中使用 libjpeg 在 CMYK 中保存灰度
【发布时间】:2014-06-01 02:52:42
【问题描述】:

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

float *arr 是一个带有 size 元素的浮点数组。我想根据需要将此数组保存为带有IJG 的libjpeg 在两个颜色空间中的JPEG:g:灰度和c:CMYK。我按照他们的示例,根据颜色空间使用JSAMPLE 元素的数量输入JSAMPLE *jsr 数组:size 元素用于灰度,4*size 元素用于 CMYK。 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。 然后我完全按照libjpeg 的源代码中的example.c 程序编写JPEG 图像。

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

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

似乎 C=0, M=0, Y=0 和 K=0 至少在这个算法和我的机器上不对应白色!?!当我只改变K通道而其余保持为零时,如何设置白色?

【问题讨论】:

    标签: c jpeg grayscale libjpeg cmyk


    【解决方案1】:

    尝试反转您的 K 通道:

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

    【讨论】:

    • 谢谢,我通过从UCHAR_MAX 中减去每个值来反转图像,因为(arr[i]-min)*m0UCHAR_MAX 之间。我更新了问题。它仍然没有像灰度那样清晰。
    • 确保 CYMK 的“白色”表示为 0,并且“黑色”表示为 UCHAR_MAX。我认为您的原始灰度(实际上是 RGB,其中 R=G=B)公式略有不同,并且准确地将您的 {min,max} 映射到范围 0..UCHAR_MAX。
    • 谢谢,但我如何确定 CMYK 是如何定义黑白的?
    • CMYK 白色:C=0,M=0,Y=0,K=0; CMYK 黑色:C/M/Y(确实未定义,但为 0 可以节省墨水),K={maximum}。由于您使用的是灰度,因此您基本上可以将 K 通道视为与 (RGB) 灰度相反。根据您对数据的使用情况,不排除使用 CMY 通道来增加图像对比度的有趣用途。
    • 我用一个新数组作为输入更新了问题。好像C=0, M=0, Y=0, K=0 不对应白色!虽然我同意理论上应该!所以我想我做错了什么,但我不知道是什么!?!
    【解决方案2】:

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

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

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

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

    然后令我惊讶的是,图像起作用了。灰度(左)的灰色阴影更深,但至少通常一切都可以解释并且相当相似。我已经单独检查过,两者的绝对黑色是相同的,但是对于相同的像素值,灰度中的灰色阴影更暗。

    在我在打印件上检查它们之后(如下),结果似乎差异较小,尽管灰度中的灰色阴影更深!用我的智能手机拍摄的图像!

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

    【讨论】:

      猜你喜欢
      • 2013-02-08
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 1970-01-01
      相关资源
      最近更新 更多