【问题标题】:Javascript - Sort rgb valuesJavascript - 对 rgb 值进行排序
【发布时间】:2012-08-09 01:17:49
【问题描述】:

使用 javascript/jquery,我想将 rgba 值数组排序为可见光谱的颜色。通过这样做,类似的阴影应该聚集在一起。是否有插件可以做到这一点,或者我将如何去做?

频谱图:http://www.gamonline.com/catalog/colortheory/images/spectrum.gif

【问题讨论】:

  • 我认为您会将 RGB 颜色转换为 HSV,然后按色调和其他两个值作为辅助键排序(根据您的喜好)。

标签: javascript arrays sorting colors


【解决方案1】:

披露:我是下面推荐的库的作者。

如果您不介意使用库,这里是 Oriol 详细回复的更简洁版本。它使用sc-color library:

var sorted = colorArray.sort(function(colorA, colorB) {
    return sc_color(colorA).hue() - sc_color(colorB).hue();
});

【讨论】:

  • 对于我需要的东西,Oriol 的方法对我来说似乎不错,因为这个库对于我的需要来说有点大。将来我可能会使用它,因为它看起来很有趣,谢谢!
  • 本,你为我节省了很多时间。谢谢你,谢谢你,谢谢你。我一直在玩颜色排序,发现按色调、饱和度和亮度排序比仅按色调排序产生的排序在视觉上更一致。当然,我正在使用数百种颜色,其中许多具有相同的色调和饱和度。
  • 更新了指向 Github 存储库的链接(并使用新的库名称)
【解决方案2】:

如果你的颜色数组是这样的:

var rgbArr = [c1, c2, c3, ...]

其中每种颜色ci 是一个由 0 到 255 之间的三个数字组成的数组

ci = [red, green, blue]

然后,您可以使用此函数将颜色转换为 HSL

function rgbToHsl(c) {
  var r = c[0]/255, g = c[1]/255, b = c[2]/255;
  var max = Math.max(r, g, b), min = Math.min(r, g, b);
  var h, s, l = (max + min) / 2;

  if(max == min) {
    h = s = 0; // achromatic
  } else {
    var d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch(max){
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  return new Array(h * 360, s * 100, l * 100);
}

并按色调排序

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and keep track of original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});

这是一个可运行的示例(感谢Ionică Bizău):

function display(container, arr) {
  container = document.querySelector(container);
  arr.forEach(function(c) {
    var el = document.createElement("div");
    el.style.backgroundColor = "rgb(" + c.join(", ") + ")";
    container.appendChild(el);
  })
}
function rgbToHsl(c) {
  var r = c[0] / 255,
      g = c[1] / 255,
      b = c[2] / 255;
  var max = Math.max(r, g, b),
      min = Math.min(r, g, b);
  var h, s, l = (max + min) / 2;

  if (max == min) {
    h = s = 0; // achromatic
  } else {
    var d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r:
        h = (g - b) / d + (g < b ? 6 : 0);
        break;
      case g:
        h = (b - r) / d + 2;
        break;
      case b:
        h = (r - g) / d + 4;
        break;
    }
    h /= 6;
  }
  return new Array(h * 360, s * 100, l * 100);
}

var rgbArr = [];
for (var i = 0; i < 100; ++i) {
  rgbArr.push([
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256),
    Math.floor(Math.random() * 256)
  ]);
}
display("#before", rgbArr);

var sortedRgbArr = rgbArr.map(function(c, i) {
  // Convert to HSL and keep track of original indices
  return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
  // Sort by hue
  return c1.color[0] - c2.color[0];
}).map(function(data) {
  // Retrieve original RGB color
  return rgbArr[data.index];
});
display("#after", sortedRgbArr);
#before > div,
#after > div {
  width: 1%;
  height: 20px;
  display: inline-block;
}
Random colors: <div id="before"></div>
Same colors, sorted by hue: <div id="after"></div>

sortedRgbArr 将包含rgbArr 的 rgb 颜色,其排序或多或少类似于可见光谱的颜色。

问题在于 HSL 频谱如下所示:

你的光谱很奇怪,因为它没有所有颜色,比如粉红色。

我猜那是因为自然界中不存在粉红色,它是光谱中相反极端颜色的组合。但是我们有 rgb 格式,所以你必须决定你想要它在哪里。

此外,您的光谱似乎是从低波长到高波长,而不是频率。但是,您的频谱与 HSL 的频谱相反。

如果您希望它像您的频谱一样,请将 c1.color[0] - c2.color[0] 替换为 c2.color[0] - c1.color[0]

【讨论】:

  • 谢谢! soectrum 图像只是作为帮助解释我正在努力实现的目标的指南。你帮了我很多,所以谢谢你!
  • 这是一个很好的答案! Tho,我有一个问题,过渡不像频谱那样平滑:jsfiddle.net/3s5hv9un/3 如何解决?我认为这与光度有关。
  • @IonicăBizău 我的答案按色调排序,但 HSL 也有饱和度和价值。例如,您可以使用几乎不饱和的红色和几乎不饱和的绿色。它们可能看起来几乎相同的灰色,但在不同的地方排序。
  • 我觉得按色调排序是不够的。还有另一种方法可以按彩虹色顺序对颜色进行排序吗?谢谢!
  • @IonicăBizău 然后你应该定义你想要的颜色空间,将 RGB 颜色转换到那个空间,然后在那里排序。没有明显的答案。
猜你喜欢
  • 2021-08-19
  • 2011-11-16
  • 2012-09-16
  • 2019-12-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-13
相关资源
最近更新 更多