如何找到N种颜色的平均值?

时间:2013-07-06 21:23:15

标签: javascript colors color-space lab-color-space

我正在寻找一种方法来查找未指定数量的颜色的平均值。我花了很多时间寻找一种方法来做到这一点。首先,我尝试将我的颜色转换为CMYK并对它们进行平均,但这并没有提供我预期的结果。然后我在几个不同的地方看到,将颜色转换为CIE L * a * b *空间,然后平均是这样做的首选方式。所以我查找了如何将RGB颜色转换为LAB空间并将其转换为Javascript所需的算法来实现这一目标。

既然我在LAB空间中拥有自己的颜色,我认为它就像找到我的颜色的平均值一样简单,所以我写了这个函数来实现这个技巧:

color.mixRGB = function() {
    var cols = Array.prototype.slice.call(arguments),
        i = cols.length,
        lab = {l: 0, a: 0, b: 0};

    while(i--) {
        if (typeof cols[i].r === "undefined" && typeof cols[i].g === "undefined" && typeof cols[i] === "undefined") {
            console.log("Not enough parameters supplied for color " + i + ".");
            return;
        }

        if(cols[i].r === 0 && cols[i].g === 0 && cols[i].b === 0) {
            cols.splice(i, 1);
        } else {
            cols[i] = color.RGBtoLAB(cols[i]);
            lab.l += cols[i].l;
            lab.a += cols[i].a;
            lab.b += cols[i].b;            
        }
    }

    lab.l /= cols.length;
    lab.a /= cols.length;
    lab.b /= cols.length;

    return color.LABtoRGB(lab);
};

如果我在函数中输入RGB(255,0,0)和RGB(0,0,255),我会得到RGB(202,-59,136)。这种颜色几乎没有接近Color Hexa所说的那两个RGB的平均值,即RGB(128,0,128),a.k.a紫色。

我回过头来看了所有代码,到目前为止,我已经设法通过对Color Hexa和{{3进行双重和三重检查来确定问题不在于我的任何转换算法}}。这意味着要么a)问题必须在于我如何平均颜色或b)我被误导了,我不应该尝试在CIE L * a * b *空间中混合颜色。

我到底错过了什么?使用我当前的算法,为什么平均RGB(255,0,0)和RGB(0,0,255)不能给我与Color Hexa(甚至视觉估计)提供的相同结果? (EasyRGB我的问题)

2 个答案:

答案 0 :(得分:3)

假设您的颜色由R0,G0,B0和R1,G1,B1定义。然后混合/平均颜色将具有以下RGB值:

RA = (R0+R1)/2;
GA = (G0+G1)/2;
BA = (B0+B1)/2;

基本上就是这样。

答案 1 :(得分:2)

null返回表示出现错误。

color.mixRGB = function() {
   var cols = Array.prototype.slice.call(arguments),
       i = cols.length,
       rTotal = 0, gTotal = 0, rTotal = 0, colTotal = 0;

   while(i--) {
       // NOTE: you had && in your code, I think they should be ||
       if (typeof cols[i].r === "undefined" || typeof cols[i].g === "undefined" || typeof cols[i] === "undefined") {
            console.log("Not enough parameters supplied for color " + i + ".");
            return null;
        }
        colTotal++;
        rTotal += cols[i].r;
        gTotal += cols[i].g;
        bTotal += cols[i].b;
    }
    if(colTotal === 0) return null;

    // I am not sure what you are trying to return, just build it up with your rgb values
    return (new color(Math.round(rTotal / colTotal), Math.round(gTotal / colTotal), Math.round(bTotal / colTotal)));
};