rgbuicolorcolor-spacehsb

How do I create a desaturated version of a Display P3 color?


I have a color UIColor(displayP3Red: 1, green: 0, blue: 0.8, alpha: 1). I want to create a desaturated version of this — with the same hue and brightness, but less saturation, like half the saturation of the original. How do I do this?


Solution

  • extension UIColor {    
      // Calling this with 0.5 as argument returns a color whose saturation is 50% of that of the receiver.
      func desaturatedBy(fraction: CGFloat) -> UIColor {
        var hue: CGFloat = 0
        var saturation: CGFloat = 0
        var brightness: CGFloat = 0
        var alpha: CGFloat = 0
        let success = getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
        assert(success)
    
        saturation *= fraction
    
        return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)
      }
    }
    

    This works because the getter returns HSB in the extended sRGB color space, and UIColor's initialiser takes HSB in the extended sRGB color space, too. So we don't need to do any color space conversion.