Skip to content

Instantly share code, notes, and snippets.

@adamgraham
Created May 28, 2019 03:42
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/a261d49997eb6afa86027c6f335d642d to your computer and use it in GitHub Desktop.
Save adamgraham/a261d49997eb6afa86027c6f335d642d to your computer and use it in GitHub Desktop.
An extension of the iOS class UIColor to provide conversion to and from HSI (hue, saturation, intensity) colors.
/// An extension to provide conversion to and from HSI (hue, saturation, intensity) colors.
extension UIColor {
/// The HSI (hue, saturation, intensity) components of a color.
struct HSI: Hashable {
/// The hue component of the color, in the range [0, 360°].
var hue: CGFloat
/// The saturation component of the color, in the range [0, 100%].
var saturation: CGFloat
/// The intensity component of the color, in the range [0, 100%].
var intensity: CGFloat
}
/// The HSI (hue, saturation, intensity) components of the color.
var hsi: HSI {
var (r, g, b) = (CGFloat(), CGFloat(), CGFloat())
getRed(&r, green: &g, blue: &b, alpha: nil)
var h = CGFloat()
getHue(&h, saturation: nil, brightness: nil, alpha: nil)
let sum = r + g + b
let i = sum / 3.0
let s = 1.0 - (min(r, g, b) / i)
return HSI(hue: h * 360.0,
saturation: s.isNaN ? 0.0 : s * 100.0,
intensity: i * 100.0)
}
/// Initializes a color from HSI (hue, saturation, intensity) components.
/// - parameter hsi: The components used to initialize the color.
/// - parameter alpha: The alpha value of the color.
convenience init(_ hsi: HSI, alpha: CGFloat = 1.0) {
let r: CGFloat
let g: CGFloat
let b: CGFloat
let h = hsi.hue
let s = hsi.saturation / 100.0
let i = hsi.intensity / 100.0
if h < 120.0 {
b = i * (1.0 - s)
r = i * (1.0 + (s * cos(deg2rad(h)) / cos(deg2rad(60.0 - h))))
g = 3.0 * i - b - r
} else if h < 240.0 {
r = i * (1.0 - s)
g = i * (1.0 + (s * cos(deg2rad(h - 120.0)) / cos(deg2rad(180.0 - h))))
b = 3.0 * i - r - g
} else {
g = i * (1.0 - s)
b = i * (1.0 + (s * cos(deg2rad(h - 240.0)) / cos(deg2rad(300.0 - h))))
r = 3.0 * i - g - b
}
self.init(red: r, green: g, blue: b, alpha: alpha)
}
}
// MARK: Helpers
/// Converts degrees to radians. 1° × π/180 = 0.01745rad
/// - parameter degrees: The amount of degrees to convert to radians.
/// - returns: The amount of radians equal to the amount of degrees.
private func deg2rad(_ degrees: CGFloat) -> CGFloat {
return degrees * .pi / 180.0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment