如何计算两个UIColor实例之间的颜色对比度

时间:2017-02-20 23:04:41

标签: ios swift uicolor

我正在寻找一种简洁的方法来计算Swift中两个UIColor实例之间的颜色对比度。我发现了一些接近但过于复杂或过时的例子。

2 个答案:

答案 0 :(得分:12)

UIColor扩展,对比度和亮度

以下UIColor扩展名包括静态和实例对比度方法。包含奖励亮度方法,因为它由静态contrastRatio(between:and:)方法使用。

import UIKit

extension UIColor {

    static func contrastRatio(between color1: UIColor, and color2: UIColor) -> CGFloat {
        // https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests

        let luminance1 = color1.luminance()
        let luminance2 = color2.luminance()

        let luminanceDarker = min(luminance1, luminance2)
        let luminanceLighter = max(luminance1, luminance2)

        return (luminanceLighter + 0.05) / (luminanceDarker + 0.05)
    }

    func contrastRatio(with color: UIColor) -> CGFloat {
        return UIColor.contrastRatio(between: self, and: color)
    }

    func luminance() -> CGFloat {
        // https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests

        let ciColor = CIColor(color: self)

        func adjust(colorComponent: CGFloat) -> CGFloat {
            return (colorComponent < 0.03928) ? (colorComponent / 12.92) : pow((colorComponent + 0.055) / 1.055, 2.4)
        }

        return 0.2126 * adjust(colorComponent: ciColor.red) + 0.7152 * adjust(colorComponent: ciColor.green) + 0.0722 * adjust(colorComponent: ciColor.blue)
    }
}

使用示例

// static method
let contrastRatio1 = UIColor.contrastRatio(between: UIColor.black, and: UIColor.white)
print(contrastRatio1) // 21.0

// instance method
let contrastRatio2 = UIColor.black.contrastRatio(with: UIColor.white)
print(contrastRatio2) // 21.0

答案 1 :(得分:0)

如果在WatchOS不可用的情况下为CoreImage进行构建,或者由于任何原因您不想依赖CoreImage并因此CIColor不可用,请替换@Mobile Dan's luminance函数具有:

  private func luminance() -> CGFloat {
  // https://www.w3.org/TR/WCAG20-TECHS/G18.html#G18-tests

    func adjust(colorComponent: CGFloat) -> CGFloat {
      return (colorComponent < 0.03928) ? (colorComponent / 12.92) : pow((colorComponent + 0.055) / 1.055, 2.4)
    }

    var red: CGFloat = 0
    var green: CGFloat = 0
    var blue: CGFloat = 0
    var alpha: CGFloat = 0
    getRed(&red, green: &green, blue: &blue, alpha: &alpha)

    return 0.2126 * adjust(colorComponent: red)
      + 0.7152 * adjust(colorComponent: green)
      + 0.0722 * adjust(colorComponent: blue)
  }