59

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.

pkamb
  • 33,281
  • 23
  • 160
  • 191
Rahul Vyas
  • 28,260
  • 49
  • 182
  • 256
  • 8
    A side note; you should look at naming conventions. `getColor` is bad for two reasons, first it uses the get prefix that is a common mistake for Java-devs, secondly it do not describe what kind of color it is. A better name is probably `userSelectedColor`. Look at how UIKit name getters, and properties, and follow suit. – PeyloW Sep 30 '09 at 08:26
  • @PeyloW, How does `userSelectedColor` describe "what kind of color it is" better than `getUserSelectedColor`? Knowing that without the `get` prefix, it's the exact same thing. I personally don't understand why Apple recommends not to use the `get` prefix. I use it in some cases for easier autocomplete, and to avoid possible clashes with private APIs. For example, I have a category on `UIColor` and I can easily type `[UIColor get` and see a list of all my methods. And if I want a dark red color, `darkRedColor` would cause problems if Apple decides to add it too, but `getDarkRedColor` wouldn't. – Iulian Onofrei Apr 10 '19 at 08:24

10 Answers10

120

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));
PeyloW
  • 36,742
  • 12
  • 80
  • 99
  • Like masking away rounded corners and such? Sure add a new question. – PeyloW Sep 30 '09 at 11:17
  • Hi PeyloW! I have used the same but it is giving the green color components when i pass black color. do you know why this is happening YOu can see my same posting here also-> http://stackoverflow.com/questions/4155642/how-to-get-color-components-of-a-cgcolor-correctly – Ganesh Nov 11 '10 at 14:57
  • 1
    @Ganesh - This only works for RGB colors, `+[UIColor blackColor]` is not a RGB color and only have a single color component for *brightness*. – PeyloW May 31 '11 at 13:48
  • 1
    I've proposed a solution that takes into account non-RGB colours. – Willster Jul 22 '12 at 10:22
23

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];

}
Willster
  • 2,526
  • 1
  • 32
  • 32
12

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
Maetschl
  • 1,330
  • 14
  • 23
Axel Guilmin
  • 11,454
  • 9
  • 54
  • 64
8

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.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
4

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.

unwind
  • 391,730
  • 64
  • 469
  • 606
2

you just simple doing this

CGFloat red,green,blue,alpha;

[UIColorobject getRed:&red green:&green blue:&blue alpha:&alpha];

in red,green,blue and alpha you get rgb value if you have any question please ask...

Thanks

Waseem Shah
  • 2,219
  • 23
  • 23
1

I think this would be a way to go. If you need to use alpha parameter as well, you can interpolate alpha from input like you do for R G and B.

- (UIColor *)getColorBetweenColor:(UIColor *)color1 andColor:(UIColor *)color2 percentage:(CGFloat)percent {
    CGFloat red1, green1, blue1, alpha1;
    CGFloat red2, green2, blue2, alpha2;

    [color1 getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
    [color2 getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];

    double resultRed = red1 + percent * (red2 - red1);
    double resultGreen = green1 + percent * (green2 - green1);
    double resultBlue = blue1 + percent * (blue2 - blue1);

    return [UIColor colorWithRed:resultRed green:resultGreen blue:resultBlue alpha:1];
}
Aleksandar
  • 1,457
  • 13
  • 30
1

This snippet of code should work with both RGB and grayscale:

CGFloat *components = (CGFloat *) CGColorGetComponents(<UIColor instance>.CGColor);
if(CGColorGetNumberOfComponents(<UIColor instance>.CGColor) == 2)
{
  //assuming it is grayscale - copy the first value
  components[2] = components[1] = components[0];
}
manicaesar
  • 5,024
  • 3
  • 26
  • 29
0

Just add the property ColorLiteral as shown in the example. Xcode will prompt you with a whole list of colors which you can choose.

self.view.backgroundColor = ColorLiteral 
piet.t
  • 11,718
  • 21
  • 43
  • 52
puneeth
  • 743
  • 7
  • 8
0

Here are some useful macros I've made for this and other color controls:

In your case you would just use

getRGBA(myColor, red, green, blue, alpha);

NSLog(@"Red Value: %f", red);
NSLog(@"Blue Value: %f", green);
NSLog(@"Green Value: %f", blue);

Macros:

#define rgba(r,g,b,a) [UIColor colorWithRed:((float)(r))/255.0f green:((float)(g))/255.0f blue:((float)(b))/255.0f alpha:a]
#define rgb(r,g,b) rgba(r, g, b, 1.0f)

#define rgbaf(r,g,b,a) [UIColor colorWithRed:(r) green:(g) blue:(b) alpha:a]
#define rgbf(r,g,b) rgbaf(r, g, b, 1.0f)

#define rgba_fromColor(__color, __r, __g, __b, __a) \
CGFloat __r, __g, __b, __a;\
UIColor *__unpackedColor = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:__color]];/*Bring system colors into compatible color-space (e.g. DarkGrayColor)*/\
[__unpackedColor getRed:&__r green:&__g blue:&__b alpha:&__a];
#define getRGBA(__color, __r, __g, __b, __a) rgba_fromColor(__color, __r, __g, __b, __a)

#define getRed(__color)  (\
(^float (void){\
rgba_fromColor(__color, r, g, b, a);\
return r;\
})()\
)

#define getGreen(__color)  (\
(^float (void){\
rgba_fromColor(__color, r, g, b, a);\
return g;\
})()\
)

#define getBlue(__color)  (\
(^float (void){\
rgba_fromColor(__color, r, g, b, a);\
return b;\
})()\
)

#define getAlpha(__color)  (\
(^float (void){\
rgba_fromColor(__color, r, g, b, a);\
return a;\
})()\
)










#define hsba(h,s,b,a) [UIColor colorWithHue:((float)(h))/360.0f saturation:((float)(s))/100.0f brightness:((float)(b))/100.0f alpha:a]
#define hsb(h,s,b) hsba(h, s, b, 1.0f)

#define hsbaf(h,s,b,a) [UIColor colorWithHue:(h) saturation:(s) brightness:(b) alpha:a]
#define hsbf(h,s,b) rgbaf(h, s, b, 1.0f)

#define hsba_fromColor(__color, __h, __s, __b, __a) \
CGFloat __h, __s, __b, __a;\
UIColor *__unpackedColor = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:__color]];/*Bring system colors into compatible color-space (e.g. DarkGrayColor)*/\
[__unpackedColor getHue:&__h saturation:&__s brightness:&__b alpha:&__a];
#define getHSBA(__color, __h, __s, __b, __a) hsba_fromColor(__color, __h, __s, __b, __a)

#define getHue(__color)  (\
(^float (void){\
hsba_fromColor(__color, h, s, b, a);\
return h;\
})()\
)

#define getSaturation(__color)  (\
(^float (void){\
hsba_fromColor(__color, h, s, b, a);\
return s;\
})()\
)

#define getBrightness(__color)  (\
(^float (void){\
hsba_fromColor(__color, h, s, b, a);\
return b;\
})()\
)

/*
///already defined in RGBA macros
#define getAlpha(__color)  (\
(^float (void){\
hsba_fromColor(__color, h, s, b, a);\
return a;\
})()\
)
*/
Community
  • 1
  • 1
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195