lsama
lsama

Reputation: 319

Find hue, saturation, brightness and alpha of a UIColor

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

Upvotes: 2

Views: 3558

Answers (1)

David Rönnqvist
David Rönnqvist

Reputation: 56625

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) 

Upvotes: 10

Related Questions