为什么我的混色功能不能按预期工作?

时间:2011-11-20 22:56:52

标签: javascript colors

我有这个函数,它有两个参数。它们是[r, g, b]格式的数组。

function mix(color1, color2) 
{
    var r = Math.round((color1[0] + color2[0])/2);
    var g = Math.round((color1[1] + color2[1])/2);
    var b = Math.round((color1[2] + color2[2])/2);

    return [r, g, b];
}

如果我尝试混合红色(255,0,0)和蓝色(0,0,255),tt会给我[128,0,128],这是紫色的。但是如果我尝试混合蓝色(0,0,255)和黄色(255,255,0)

console.log(mix([255,0,0], [0,0,255]));
console.log(mix([255,255,0], [0,0,255]));

它给了我灰色[128, 128, 128],而不是绿色。为什么会这样?

5 个答案:

答案 0 :(得分:4)

您需要将颜色转换为HSL或HSV颜色模型(此处或Google上有大量样本,例如this page)。

然后使用生成的数字进行平均,然后转换回RGB。

这将确保饱和度和亮度保持一致,并为您提供两种原始颜色之间正确的色调。

使用上面链接的库:

function mix(color1, color2, amount) 
{
    if (typeof amount === "undefined") {
        amount = 0.5;
    }

    var hsl1 = rgbToHsl.apply(this, color1);
    var hsl2 = rgbToHsl.apply(this, color2);

    var h = amount * hsl1[0] + (1 - amount) * hsl2[0];
    var s = amount * hsl1[1] + (1 - amount) * hsl2[1];
    var l = amount * hsl1[2] + (1 - amount) * hsl2[2];

   return hslToRgb(h, s, l);
}

注意:这是未经测试的代码(算法是正确的,我实际上并没有把它扔到解释器上),结果可能需要四舍五入。但是对于奖励积分,它还允许您指定50/50以外的混合比例。

答案 1 :(得分:2)

因为您将结果颜色计算为两种基色的芳香平均值。

根据您的混合,颜色以不同的方式工作。如果你要混合多种不同颜色的颜料,结果会很暗,几乎是黑色的。但如果你想混合不同颜色的灯光,那么结果几乎是白色的。首先定义你想要模拟的过程 - 我敢打赌它是一个类似于混合颜料的过程,对吗?

混合颜色的两种基本方法是:

  • 减法混合,看起来像这样:

    enter image description here

  • 添加剂混合,看起来像:

    enter image description here

您需要的是减色混色,其输出应为RGB符号。

答案 2 :(得分:2)

这里有两个主要问题:

加法与减法混合 - 这很容易阅读

但我认为,主要问题是蓝色和黄色涂料不会变绿。你想到的蓝色实际上并不是蓝色:更多的是青色,或者至少是蓝色,有一些绿色的变化。

纯粹的“蓝色”既不温暖(朝向红色)也不酷(朝向黄色/绿色)并且在油漆中会像深蓝色的红色 - 纯蓝色,但你会认为它是一种深蓝色(几乎是海军蓝色)。

当油漆与黄色混合时,你不会得到一个明亮的绿色,更多的是暗灰色。在油漆中要获得混合物中明亮的油漆颜色,必须使用色轮上彼此不相交的颜色,但事实上理想情况下尽可能接近,所以明亮的绿色实际上只能在油漆中获得从绿色的蓝色和绿色的黄色混合 - 即。他们是邻居。

绿色仍然不如纯绿色那么明亮。这不能在减法(油漆混合)中完成 - 组合颜色和获得新的纯色只能用彩色灯光 - 即。添加剂混合,就像你在剧院看到的那样。

然而要注意添加剂混合有点违反直觉 - 而不是你的减色涂料蓝色/黄色混合给出中性灰色(理论上是黑色)实际上你会得到白色的灯......(仍然不是绿色! )。

这是一个非常复杂的领域,因为还涉及一些心理学和生理学 - 我们的大脑经常作弊或错误的颜色感知。例如。你混合黑色和黄色你得到一个深绿色 - 这与灵敏度或红色/绿色锥体有关,因为亮度降低 - 它实际上是深黄色但我们看到绿色。

答案 3 :(得分:1)

要获得您所期望的,您需要在CMY空间而不是RGB空间中工作。

这是一个简单的RGB到CMY转换器:

function rgb2cmy (r, g, b) {
  var c = 255-r;
  var m = 255-g;
  var y = 255-b;
  return [c,m,y];
}

简单地反转过程以转换回RGB:

function cmy2rgb (c, m, y) {
  var r = 255-c;
  var g = 255-m;
  var b = 255-y;
  return [r,g,b];
}

(如果你一直在关注,你会发现两个功能都做同样的事情)

答案 4 :(得分:0)

我认为你的公式很好,比如说,如果你把蓝色放在黄色旁边然后涂上一个模糊的话,那就是photoshop会做的......你会在中间变灰。蓝色和黄色不混合使绿色。红色,绿色和蓝色是电脑显示器,相机胶卷和人眼的原色。

同时,黄色是红色和绿色光的混合物,也就是说,当你看到黄色时,你眼中的红色和绿色敏感锥体会受到刺激。它可能看起来不直观,但它确实如此。在放大镜下看一下屏幕的黄色区域,你会看到它由红色和绿色点组成。

这与您在小学时所学到的相反,有时混合油漆或油墨可能最终会产生蓝色和黄色,从而产生(通常是泥泞的)绿色。因此,我不建议您更改算法,这是将两种颜色混合在一起的标准方法。只是改变你的期望。 :)