Add support for grayscale modes

This commit is contained in:
Vincent Esche 2020-01-13 14:49:02 +01:00
parent 4fcc489c3b
commit 3997359fc1
4 changed files with 40 additions and 6 deletions

View File

@ -99,7 +99,14 @@ let desaturatedColor = originalColor.desaturated()
// equivalent to
// desaturatedColor = originalColor.desaturated(amount: 0.2)
// equivalent to
// let grayscaledColor = originalColor.grayscaled(mode: .luminance)
let grayscaledColor = originalColor.grayscaled()
let grayscaledColorLuminance = originalColor.grayscaled(mode: .luminance)
let grayscaledColorLightness = originalColor.grayscaled(mode: .lightness)
let grayscaledColorAverage = originalColor.grayscaled(mode: .average)
let grayscaledColorValue = originalColor.grayscaled(mode: .value)
```
#### Adjust-hue & Complement

View File

@ -99,13 +99,25 @@ public extension DynamicColor {
/**
Creates and returns a color object converted to grayscale.
This is identical to desaturateColor(1).
- returns: A grayscale DynamicColor.
- seealso: desaturateColor:
- seealso: desaturated:
*/
final func grayscaled() -> DynamicColor {
return desaturated(amount: 1)
final func grayscaled(mode: GrayscalingMode = .lightness) -> DynamicColor {
let (r, g, b, a) = self.toRGBAComponents()
let l: CGFloat
switch mode {
case .luminance:
l = (0.299 * r) + (0.587 * g) + (0.114 * b)
case .lightness:
l = 0.5 * (max(r, g, b) + min(r, g, b))
case .average:
l = (1.0 / 3.0) * (r + g + b)
case .value:
l = max(r, g, b)
}
return HSL(hue: 0.0, saturation: 0.0, lightness: l, alpha: a).toDynamicColor()
}
/**

View File

@ -71,3 +71,19 @@ internal func roundToHex(_ x: CGFloat) -> UInt32 {
return UInt32(rounded)
}
/**
Defines the mode (i.e color space) used for grayscaling.
[More info](https://en.wikipedia.org/wiki/Lightness#Lightness_and_human_perception)
*/
public enum GrayscalingMode {
/// XYZ luminance
case luminance
/// HSL lightness
case lightness
/// RGB average
case average
/// HSV value
case value
}

View File

@ -289,7 +289,6 @@ class DynamicColorTests: XCTestCase {
func testGrayscaleColor() {
let grayscale = DynamicColor(hex: 0xc0392b).grayscaled()
let desaturated = DynamicColor(hex: 0xc0392b).desaturated(amount: 1)
XCTAssert(grayscale.isEqual(desaturated), "Colors should be the same")
}