Skip to content

Instantly share code, notes, and snippets.

@adamgraham
Last active June 2, 2019 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamgraham/1a72c374e025ad1a787b5b327be256ce to your computer and use it in GitHub Desktop.
Save adamgraham/1a72c374e025ad1a787b5b327be256ce to your computer and use it in GitHub Desktop.
An extension of the iOS class UIColor to provide conversion to and from Hunter Lab colors.
/// An extension to provide conversion to and from Hunter Lab colors.
extension UIColor {
/// XYZ tristimulus values of d65 illuminant with standard 2° observer.
private static let d65: (X: CGFloat, Y: CGFloat, Z: CGFloat) = (95.047, 100.000, 108.883)
/// The Hunter Lab components of a color - lightness (L) and chromaticity (a,b).
struct HunterLab: Hashable {
/// The lightness component of the color, in the range [0, 100] (darkest to brightest).
var L: CGFloat
/// The green-red chromaticity component of the color.
var a: CGFloat
/// The blue-yellow chromaticity component of the color.
var b: CGFloat
}
/// The Hunter Lab components of the color using a d65 illuminant and 2° standard observer.
var hunterLab: HunterLab {
let XYZ = self.XYZ
let ref = UIColor.d65
let X = XYZ.X / ref.X
let Y = XYZ.Y / ref.Y
let Z = XYZ.Z / ref.Z
let kL = sqrt(Y)
let kA = (175.0 / 198.04) * (ref.Y + ref.X)
let kB = (70.0 / 218.11) * (ref.Y + ref.Z)
var L = 100.0 * kL
var a = kA * ((X - Y) / kL)
var b = kB * ((Y - Z) / kL)
if L.isNaN { L = 0.0 }
if a.isNaN { a = 0.0 }
if b.isNaN { b = 0.0 }
return HunterLab(L: L, a: a, b: b)
}
/// Initializes a color from Hunter Lab components.
/// - parameter hunterLab: The components used to initialize the color.
/// - parameter alpha: The alpha value of the color.
convenience init(_ hunterLab: HunterLab, alpha: CGFloat = 1.0) {
let ref = UIColor.d65
let kA = (175.0 / 198.04) * (ref.Y + ref.X)
let kB = (70.0 / 218.11) * (ref.Y + ref.Z)
var Y = pow(hunterLab.L / ref.Y, 2.0) * 100.0
let kL = Y / ref.Y
let kLs = sqrt(kL)
var X = (hunterLab.a / kA * kLs + kL) * ref.X
var Z = -(hunterLab.b / kB * kLs - kL) * ref.Z
if X.isNaN { X = 0.0 }
if Y.isNaN { Y = 0.0 }
if Z.isNaN { Z = 0.0 }
self.init(CIEXYZ(X: X, Y: Y, Z: Z), alpha: alpha)
}
}
@adamgraham
Copy link
Author

adamgraham commented May 13, 2019

This requires the CIEXYZ extension declared at https://gist.github.com/adamgraham/677c0c41901f3eafb441951de9bc914c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment