打印机是否打印所有cmyk色域颜色以及icc配置文件的确切用途

does printers print all of cmyk gamut colors and what is exact usage of icc profiles?

本文关键字:配置文件 icc 颜色 打印 是否 cmyk 打印机      更新时间:2023-09-26

我正在使用的代码将rgb颜色转换为cmyk,反之亦然:

/**
*
*  Javascript color conversion
*  http://www.webtoolkit.info/
*
**/
function HSV(h, s, v) {
    if (h <= 0) { h = 0; }
    if (s <= 0) { s = 0; }
    if (v <= 0) { v = 0; }
    if (h > 360) { h = 360; }
    if (s > 100) { s = 100; }
    if (v > 100) { v = 100; }
    this.h = h;
    this.s = s;
    this.v = v;
}
function RGB(r, g, b) {
    if (r <= 0) { r = 0; }
    if (g <= 0) { g = 0; }
    if (b <= 0) { b = 0; }
    if (r > 255) { r = 255; }
    if (g > 255) { g = 255; }
    if (b > 255) { b = 255; }
    this.r = r;
    this.g = g;
    this.b = b;
}
function CMYK(c, m, y, k) {
    if (c <= 0) { c = 0; }
    if (m <= 0) { m = 0; }
    if (y <= 0) { y = 0; }
    if (k <= 0) { k = 0; }
    if (c > 100) { c = 100; }
    if (m > 100) { m = 100; }
    if (y > 100) { y = 100; }
    if (k > 100) { k = 100; }
    this.c = c;
    this.m = m;
    this.y = y;
    this.k = k;
}
var ColorConverter = {
    _RGBtoHSV : function  (RGB) {
        var result = new HSV(0, 0, 0);
        r = RGB.r / 255;
        g = RGB.g / 255;
        b = RGB.b / 255;
        var minVal = Math.min(r, g, b);
        var maxVal = Math.max(r, g, b);
        var delta = maxVal - minVal;
        result.v = maxVal;
        if (delta == 0) {
            result.h = 0;
            result.s = 0;
        } else {
            result.s = delta / maxVal;
            var del_R = (((maxVal - r) / 6) + (delta / 2)) / delta;
            var del_G = (((maxVal - g) / 6) + (delta / 2)) / delta;
            var del_B = (((maxVal - b) / 6) + (delta / 2)) / delta;
            if (r == maxVal) { result.h = del_B - del_G; }
            else if (g == maxVal) { result.h = (1 / 3) + del_R - del_B; }
            else if (b == maxVal) { result.h = (2 / 3) + del_G - del_R; }
            if (result.h < 0) { result.h += 1; }
            if (result.h > 1) { result.h -= 1; }
        }
        result.h = Math.round(result.h * 360);
        result.s = Math.round(result.s * 100);
        result.v = Math.round(result.v * 100);
        return result;
    },
    _HSVtoRGB : function  (HSV) {
        var result = new RGB(0, 0, 0);
        var h = HSV.h / 360;
        var s = HSV.s / 100;
        var v = HSV.v / 100;
        if (s == 0) {
            result.r = v * 255;
            result.g = v * 255;
            result.v = v * 255;
        } else {
            var_h = h * 6;
            var_i = Math.floor(var_h);
            var_1 = v * (1 - s);
            var_2 = v * (1 - s * (var_h - var_i));
            var_3 = v * (1 - s * (1 - (var_h - var_i)));
            if (var_i == 0) {var_r = v; var_g = var_3; var_b = var_1}
            else if (var_i == 1) {var_r = var_2; var_g = v; var_b = var_1}
            else if (var_i == 2) {var_r = var_1; var_g = v; var_b = var_3}
            else if (var_i == 3) {var_r = var_1; var_g = var_2; var_b = v}
            else if (var_i == 4) {var_r = var_3; var_g = var_1; var_b = v}
            else {var_r = v; var_g = var_1; var_b = var_2};
            result.r = var_r * 255;
            result.g = var_g * 255;
            result.b = var_b * 255;
            result.r = Math.round(result.r);
            result.g = Math.round(result.g);
            result.b = Math.round(result.b);
        }
        return result;
    },
    _CMYKtoRGB : function (CMYK){
        var result = new RGB(0, 0, 0);
        c = CMYK.c / 100;
        m = CMYK.m / 100;
        y = CMYK.y / 100;
        k = CMYK.k / 100;
        result.r = 1 - Math.min( 1, c * ( 1 - k ) + k );
        result.g = 1 - Math.min( 1, m * ( 1 - k ) + k );
        result.b = 1 - Math.min( 1, y * ( 1 - k ) + k );
        result.r = Math.round( result.r * 255 );
        result.g = Math.round( result.g * 255 );
        result.b = Math.round( result.b * 255 );
        return result;
    },
    _RGBtoCMYK : function (RGB){
        var result = new CMYK(0, 0, 0, 0);
        r = RGB.r / 255;
        g = RGB.g / 255;
        b = RGB.b / 255;
        result.k = Math.min( 1 - r, 1 - g, 1 - b );
        result.c = ( 1 - r - result.k ) / ( 1 - result.k );
        result.m = ( 1 - g - result.k ) / ( 1 - result.k );
        result.y = ( 1 - b - result.k ) / ( 1 - result.k );
        result.c = Math.round( result.c * 100 );
        result.m = Math.round( result.m * 100 );
        result.y = Math.round( result.y * 100 );
        result.k = Math.round( result.k * 100 );
        return result;
    },
    toRGB : function (o) {
        if (o instanceof RGB) { return o; }
        if (o instanceof HSV) { return this._HSVtoRGB(o); }
        if (o instanceof CMYK) { return this._CMYKtoRGB(o); }
    },
    toHSV : function (o) {
        if (o instanceof HSV) { return o; }
        if (o instanceof RGB) { return this._RGBtoHSV(o); }
        if (o instanceof CMYK) { return this._RGBtoHSV(this._CMYKtoRGB(o)); }
    },
    toCMYK : function (o) {
        if (o instanceof CMYK) { return o; }
        if (o instanceof RGB) { return this._RGBtoCMYK(o); }
        if (o instanceof HSV) { return this._RGBtoCMYK(this._HSVtoRGB(o)); }
    }
}

例如,当我将打印机上打印色域之外的颜色rgb(8,56213)转换为cmyk:时

console.log( ColorConverter.toCMYK(new RGB(8, 56, 213)) );

给我这个代码:cmyk(96%,74%,0.16%)

现在,一台用cmyk颜色打印的打印机可以打印所有cmyk的颜色吗?它是否也打印cmyk(96%,74%,0.16%)??如果是,ICC配置文件的确切用途是什么??

你需要理解的是,颜色是感知的,而不是客观的。想象一辆红色的汽车,现在想象同一辆红色汽车晚上在路灯下停在停车场。同一辆车现在看起来是橙色的。汽车的颜色没有改变,但照明改变了你对颜色的感知。这就是为什么在受控照明下观看颜色。

下一个感知是反射率。墨水永远无法打印出真正的金色,因为金色不仅仅是一种颜色,它是反光的。用CMYK印刷的金色看起来像芥末。

配色最重要的元素是油墨覆盖。打印一条从0%到100%的色带,色带应该是从无色到全色的连续混合。如果颜色在托叶上方80%的地方变成纯色,那么墨水就有20%的增益。如果前20%的颜色是白色(不打印),则为20%的负压增益。条纹可以同时做到这两点,从零开始20%,从满开始80%。这将根据纸张和dpi分辨率进行更改。

接下来,在2台不同的打印机上打印出青色、黄色和品红色条纹。他们看起来会不一样。这是因为染料、颜料和调色剂需要由材料制成,而材料并不完美,即使颜色条纹从0%-100%平滑过渡。

icc颜色配置文件试图理解这种混淆,即显示器与预期标准匹配,然后显示的颜色与打印输出上应该看到的颜色匹配。相机和扫描仪也需要自己的配置文件。

这对肉色调来说尤其棘手,品红色墨水的红色多一点会变成晒伤,或者青色墨水的绿色多一点会让人看起来不舒服。因此,打印机不得不使用浅品红色和浅青色,以使墨水色调更接近肉色。

即使使用好的青色、品红色和黄色墨水,当混合在一起时,它们往往会变成棕色而不是灰色,因此当观察到等量的CMY时,从CMY中减去等量并移动到黑色(K)通道。回到金的讨论,100%K不是浓黑色,所以为了使黑色成为浓黑色,即使是100%黑色,也会打印一定量的CMY,这会使黑色看起来更黑,或者可能有点蓝/黑。

清澈如泥?类似的类比是温度。RGB到CMYK的转换类似于摄氏度到华氏度的转换。但这个问题的真正答案还包括,是晴天还是阴天,太阳在天空中有多低,湿度是多少,风速是多少,你是站在柏油路上、草地上还是站在水中,水有多冷。。。icc曲线给出了"真实感觉"温度,试图将其他变量考虑在内,但即便如此,在阳光明媚的日子里站在树下,真实感觉温度也会迅速变化。因此,为了获得真正的"真实感觉",需要为每个变量创建一个概要文件。太阳需要校准到一个标准,就像液晶显示器一样。你站在下面的树需要像用来拍摄原始照片的相机一样进行校准。。。

颜色匹配的准确程度与报告温度的准确程度相似。对很多事情来说,接近就足够了,但对肤色或体温来说,10%的错误可能是致命的。