How do I get red green blue (RGB) and alpha back from a UIColor object?

48,418

Solution 1

The reason for the crash when accessing SelectedColor.CGColor could be that you do not retain the result from getColor, perhaps what you need is:

SelectedColor = [[(ColorPickerView *)alertView getColor] retain];

You can only get the RGB color component from a UIColor that is using the RGB color space, since you are using colorWithRed:green:blue:alpha: that is not a problem, but be vary of this if your code changes.

With this is mind getting the color components is really easy:

const CGFloat* components = CGColorGetComponents(SelectedColor.CGColor);
NSLog(@"Red: %f", components[0]);
NSLog(@"Green: %f", components[1]); 
NSLog(@"Blue: %f", components[2]);
NSLog(@"Alpha: %f", CGColorGetAlpha(SelectedColor.CGColor));

Solution 2

This solution works for non-RGB colours as well e.g. black or white color.

UIColor *color = [UIColor blackColor];
CGFloat red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;
// iOS 5
if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
     [color getRed:&red green:&green blue:&blue alpha:&alpha];
} else {
     // < iOS 5
     const CGFloat *components = CGColorGetComponents(color.CGColor);
     red = components[0];
     green = components[1];
     blue = components[2];
     alpha = components[3];
}

// This is a non-RGB color
if(CGColorGetNumberOfComponents(color.CGColor) == 2) {
    CGFloat hue;
    CGFloat saturation;
    CGFloat brightness;
    [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];

}

Solution 3

There is a Swift extension for that :)

extension UIColor {

    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var red: CGFloat = 0.0
        var green: CGFloat = 0.0
        var blue: CGFloat = 0.0
        var alpha: CGFloat = 0.0
        getRed(&red, green: &green, blue: &blue, alpha: &alpha)

        return (red: red, green: green, blue: blue, alpha: alpha)
    }

    var redComponent: CGFloat {
        var red: CGFloat = 0.0
        getRed(&red, green: nil, blue: nil, alpha: nil)

        return red
    }

    var greenComponent: CGFloat {
        var green: CGFloat = 0.0
        getRed(nil, green: &green, blue: nil, alpha: nil)

        return green
    }

    var blueComponent: CGFloat {
        var blue: CGFloat = 0.0
        getRed(nil, green: nil, blue: &blue, alpha: nil)

        return blue
    }

    var alphaComponent: CGFloat {
        var alpha: CGFloat = 0.0
        getRed(nil, green: nil, blue: nil, alpha: &alpha)

        return alpha
    }
}

It is compatible with Swift 4.2 and also works with 2 components colors like black, gray, etc. You can access a specific canal like so :

myColor.rgba.blue

Or, its equivalent :

myColor.blueComponent

Solution 4

In most cases this will work, unless the conversion to RGB doesn't work.

float red, green, blue, alpha;
BOOL conversionToRGBWentOk = [color getRed:&red green:&green blue:&blue alpha:&alpha];

That's what these methods are for, in fact. If the conversionToRGBWentOk is NO you'll have a problem, though.

Solution 5

I think you should have a a look here, where Ars' guide shows how to extend the UIColor class with support for accessing the color components.

Share:
48,418
Rahul Vyas
Author by

Rahul Vyas

Sr. iOS Developer, Gamer

Updated on July 08, 2022

Comments

  • Rahul Vyas
    Rahul Vyas almost 2 years

    I am getting a UIColor returned from this method:

    - (UIColor *)getUserSelectedColor {   
        return [UIColor colorWithRed:redSlider.value green:greenSlider.value blue:blueSlider.value alpha:1.0];
    }
    

    and getting color like this:

    UIColor *selectedColor = [(ColorPickerView *)alertView getUserSelectedColor];
    

    Now I want to get red, green, blue from selectedColor, in order to use those values. I want values between 0 and 1.