【问题标题】:How can I find the average of N colors?我怎样才能找到N种颜色的平均值?
【发布时间】:2013-07-06 21:23:14
【问题描述】:

我正在寻找一种方法来找到未指定颜色数量的平均值。我花了很多时间寻找一种方法来做到这一点。首先,我尝试将颜色转换为 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),也就是紫色。

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

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

【问题讨论】:

  • 在一个颜色空间中取平均值与在不同颜色空间中取平均值不同。人们不会期待同样的结果。
  • 我明白;为什么相关?
  • 因为你似乎对你得到不同的结果感到惊讶;)(虽然可能我误读了……)
  • 嗯,我希望得到一些相似的结果,如果不完全相同的话。两种颜色有一个确定的平均值,对吧? Color Hexa 似乎提供了我对平均红色和蓝色的视觉估计(紫色)的近似值,而我的算法不是。
  • Color Hexa 似乎适用于 RGB,仅取每个通道中对的平均值。

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


【解决方案1】:

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

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

基本上就是这样。

【讨论】:

  • 我想我一定是错过了什么。真的可以这么简单吗?我编写了这个算法,我只是在做一些测试。
  • 嗯,这是 Color Hexa 的方式。如果你问我,这是不对的。尝试在 HLS 或 HSB 颜色空间中执行相同的操作。 LaB 可能会对此感到困惑。
  • 好吧,这似乎可以解决问题(这当然是我所需要的)。我想我现在要接受你的回答。感谢您在我忙于过度复杂的色彩空间时成为常识的声音。 :-)
  • 你需要四舍五入,看我的解决方案。
【解决方案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)));
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2012-03-30
    • 1970-01-01
    • 2018-01-12
    相关资源
    最近更新 更多