我想做一些特殊的颜色比较。
在我的研究中,我发现不应使用RGB光谱进行比较,因为HSL & HSV等一些不同的光谱被设计为“与人类视觉感知色彩属性的方式更加接近”(quote Wikipedia)

因此,我需要一种将不同的colorSystem相互转换的方法。

对我而言,最重要的转换之一是将HEX转换为HSL(使用Swift)


因为我是个流血的初学者,所以这段代码是我到目前为止所拥有的:

// conversion HEX to HSL
HexToHSL("#F23CFF") // HSL should be "HSL: 296° 100% 62%"
func HexToHSL(_ hex: String) {
  let rgb = HexToRgb(hex)
  let r = rgb[0],
      g = rgb[1],
      b = rgb[2],
      a = rgb[3]

}

func RgbToHSL(r: Int, g: Int, b: Int) -> [Int] {
    let r = r/255, g = g/255, b = b/255;

    let max = [r, g, b].max()!, min = [r, g, b].min()!;
    let (h, s, l) = Double(max + min)*0.5; // "Expression type 'Double' is ambiguous without more context"

    if (max == min) {
        h = s = 0;
    } else {
        let d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        h /= 6;
    }
    return [ h, s, l ];
}
func HexToRgb(_ hex: String) -> [Int] {
    let hex = hex.substring(fromIndex: 1)
    var rgbValue:UInt32 = 0
    Scanner(string: hex).scanHexInt32(&rgbValue)
    let red = Int((rgbValue & 0xFF0000) >> 16),
    green = Int((rgbValue & 0x00FF00) >> 8),
    blue = Int(rgbValue & 0x0000FF),
    alpha = Int(255.0)
    return [red, green, blue, alpha]
}

非常感谢您提供任何有关如何解决从HEX到HSL的颜色转换的帮助!

注意:还有一种javascript sample用于某种颜色转换。也许很有帮助:)
编辑:我已经将rgb的代码固定为hsl,如下所示:
func RgbToHSL(_ rgb: [Int]) -> [Double] {
    let r = Double(rgb[0])/255, g = Double(rgb[1])/255, b = Double(rgb[2])/255;
    let max = [r, g, b].max()!, min = [r, g, b].min()!;
    var h = Double(max + min)*0.5,
        s = Double(max + min)*0.5,
        l = Double(max + min)*0.5;

    if (max == min) {
        h = 0
        s = 0
        l = 0
    } else {
        let 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;
          default:  break;
        }
        h /= 6;
    }
    return [ h, s, l ];
}

...但是rgb = [242, 60, 255]的结果将是[0.8222222222222223, 1.0, 0.61764705882352944]-看起来不太好,因为它应该是296° 100% 62%! :o

最佳答案

为了比较颜色,从而执行色差,您需要使用在感知上统一的颜色空间。

HSL HSV 实际上是非常差的色彩空间,因此不应将它们用于正确的比色计算,因为它们的亮度和值轴不是与诸如 CIE L*a*b* 的色彩空间相反的亮度的实际感知表示。 。

在色彩科学中,有多种方法可以计算色差,通常最简单,而假设您使用统一的色彩空间的方法就是欧氏距离。

这就是 CIE L*u*v* 使用 CIE L * a * b * 色彩空间所做的工作。 CIE注意到有些 DeltaE 值较低的颜色实际上看起来是完全不同的,这是 CIE L * a * b * 色彩空间在感知上不够均匀的副作用。从那里开始,研究产生了许多新的色差公式和新的感知均匀的色彩空间。

这是从最旧到最新的值得注意的色差公式和可感知的统一色空间的详尽列表,请注意实现复杂度几乎遵循该列表顺序:

  • DeltaE CIE 1976
  • DeltaE CIE 1976
  • DeltaE CMC
  • DeltaE CIE 1994
  • DIN99
  • IPT
  • DeltaE CIE 2000CIECAM02
  • CAM02-UCS
  • CAM16 & CAM16-UCS
  • ICTCP

  • 我建议看一下像 ICTCP JzAzBz 之类的东西,它们提供良好的性能并且实现起来并不复杂,或者至少使用欧氏距离的 CIE L * a * b * 但避免使用 HSL ojit_r和 HSV

    我们为JzAzBz中提到的所有内容提供了参考实现。

    10-07 19:49