1

I have a red object: red_object = UIColor.red.cgColor

I would like to get the hue saturation brightness and alpha parameters of this 'red' so I can recode my red &object using more specific parameters.

This exercise would be a once off but I need these parameters.

I have tried cgColor.components but I don't think this is the right function:

red_test = UIColor.red.cgColor
let output = red_test.components
print(output) = Optional([1.0, 0.0, 0.0, 1.0])

but if I run the following

let circlePathT = UIBezierPath(arcCenter: CGPoint(x: x_mid,y: y_mid), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
let red_object = CAShapeLayer()
red_object.fillColor = UIColor(hue: 1, saturation: 0, brightness: 0, alpha: 1).cgColor

I get a black circle, not red. More specifically I am expecting

red_object.fillColor = UIColor(hue: 1, saturation: 0, brightness: 0, alpha: 1).cgColor

to equal

red_test = UIColor.red.cgColor

but it isn't

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
lsama
  • 199
  • 3
  • 13

1 Answers1

10

Why you're getting the "wrong" component values

You'll find that the components of a CGColor is the values of the components in the color's color space. Since there is no hue-saturation-brighness-alpha color space model, these won't be the color's hue saturation, or brightness.

Instead, you're likely to find either red-green-blue-alpha values for colors in an RGB color space model (like UIColor.red) or white-alpha values for colors in a monochrome color space model (like UIColor.gray).

UIColor.red.cgColor.components        // [1.0, 0.0, 0.0, 1.0]
UIColor.red.cgColor.colorSpace?.name. // kCGColorSpaceExtendedSRGB

UIColor.gray.cgColor.components       // [0.5, 1.0]
UIColor.gray.cgColor.colorSpace?.name // kCGColorSpaceExtendedGray

Looking at the component values for red (1, 0, 0, 1) it makes sense that these wouldn't be hue, saturation, brightness, and alpha — since any color with a 0 brightness would be completely black, and any color with 0 saturation would be fully desaturated.

Instead, we would expect both the brightness and saturation of red to be 100%, like how they appear in the color picker:

the HSB values in the color picker for "red"

How to get the hue, saturation, brightness, and alpha of a color

If you want to get the hue, saturation, brightness, and alpha of a color — no matter the color space it is in — you'd use getHue(_:saturation:brightness:alpha:) and pass four mutable pointers to CGFloat values:

var hue        : CGFloat = 0
var saturation : CGFloat = 0
var brightness : CGFloat = 0
var alpha      : CGFloat = 0
let couldBeConverted = UIColor.red.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
if couldBeConverted {
    // The color is in a compatible color space, and the variables
    // `hue`, `saturation`, `brightness`, and `alpha` have been
    // changed to contain these values.
}

Note that this method is on UIColor. If you have a CGColor reference then you'll have to create a UIColor to read its HSBA components:

UIColor(cgColor: yourCGColor) 
David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • Thanks this worked! Excellent explanation, i really needed that – lsama Nov 20 '17 at 14:01
  • 3
    @Isama I see that you have no accepted questions. If it answers your question then you should consider accepting it to let others know that this question has been answered. For more information see: [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers?) – David Rönnqvist Nov 20 '17 at 16:09