2011-11-20 211 views
0

我有这个函数需要两个参数。它们是[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],而不是绿色。这是为什么发生?

+1

你真的应该在该函数中用'var'声明“r”,“g”和“b”,不管这是否是问题的原因。 – Pointy

+0

@Pointy同样的结果。 – Aillyn

+0

你的脚本也适合我。 – Pointy

回答

2

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

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

两种基本的方法是:

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

    enter image description here

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

    enter image description here

您需要的是减色混色,其输出应为RGB表示法。

+0

确实如此。我怎样才能用Javascript做到这一点? – Aillyn

+1

@pessimopoppotamus:我相信最简单的方法是将您的颜色转换为** CMY **,然后只需添加它们,然后将结果转换回** RGB **。它看起来像这样:1)yellow('rgb(255,255,0)')将成为'CMY(0.0,0.0,1.0)',2)blue('rgb(0,0,255)')将成为CMY 1.0,0.0,0.0)',3),黄色和蓝色的总和将是CMY(0,0,1)+ CMY(1,0,0)= CMY(1,0,1)',这是绿色('rgb(0,255,0)')。 – Tadeck

+1

@Tadeck你的转换是错误的 - 蓝色是不是'CMY(1,0,0)',它是'CMY(1,1,0)',如果你将它添加到黄色,你将获得CMY(1,1, 1)'这是_black_ – Alnitak

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); 
} 

NB:

使用上面链接库,这是未经测试的代码(该算法是正确的,我只是没有真正在解释它扔还),结果可能需要圆润。但是,对于奖励积分,它还允许您指定50/50以外的混合比例。

+0

我无法像现在这样工作。我可能仍然在做一些错误 - 但未定义应该是一个字符串,使它成为一个可选参数if(typeof amount ===“undefined”){' – mikevoermans

+0

@mikevoermans是的,你是对的!我修正了这个问题。 – Alnitak

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]; 
} 

(如果你一直在关注,你就会明白这两个功能都做同样的事情)

0

我认为你的公式工作正常,这是什么,比如说,如果你将蓝色ne xt变黄并涂抹模糊......你会在中间变灰。蓝色和黄色不会混合成绿色。红色,绿色和蓝色是计算机显示器,相机胶片和人眼的初选。

与此同时,黄色是红色和绿色光的混合物,也就是说,当你看到黄色时,红色和绿色敏感的视锥会刺激你的眼睛。它可能看起来并不直观,但这是事实。在放大镜下查看屏幕上的黄色区域,您会看到它由红色和绿色点组成。

这与您在小学中学到的东西形成了对比,有时混合涂料或油墨可能会以蓝色和黄色为主(通常是泥泞的)绿色。所以,我不建议你改变你的算法,这是一种将两种颜色混合在一起的标准方法。只是改变你的期望。 :)这里

2

2个主要问题:

与添加剂混合消减 - 这是很容易了解

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

纯蓝色既不是温暖的(朝着红色),也不是凉爽的(朝着黄色/绿色),而在油漆中就像群青红色的阴影 - 一种纯粹的蓝色,但你会认为是相当黑暗(几乎藏青色)的蓝色。

当在油漆中混合黄色时,你不会得到鲜绿色,更暗淡的灰色。在油漆中获得混合光亮的油漆颜色,必须使用色轮上彼此不相交的颜色,但实际上尽可能接近理想的颜色,因此鲜绿色实际上只能在油漆中获得从混合绿色的蓝色和绿色的黄色 - 即。他们是邻居。

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

但是请注意,添加剂混合有点违反直觉 - 而不是您的减色油漆蓝色/黄色混合提供中性灰色(理论上黑色)实际上灯会变白......(仍不是绿色!)。

这是一个非常复杂的领域,因为也涉及到一些心理学和生理学 - 我们的大脑欺骗或错误的色彩感知定期。例如。你将黑色和黄色混合在一起就会得到深绿色 - 这与感光度或红/绿色锥体有关,因为亮度降低 - 实际上它是深黄色,但是我们看到绿色。

+1

你可以在你的文章中添加一些新行吗?这几乎不可以听到.. – j0k

相关问题