Convert NSColor to RGB
Asked Answered
K

7

9

I'm trying to convert an NSColor to RGB, but it seems to give an entirely incorrect result:

NSColor *testColor = [NSColor colorWithCalibratedWhite:0.65 alpha:1.0];

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

I get back : red = 0.65 - green = 1.0 - blue = 0.0 and alpha is 1.0 - which results in an entirely different color. (It should be gray, now it's green).

Am I doing something wrong?

Krever answered 28/3, 2013 at 13:18 Comment(0)
B
8

You need to convert the color to an RGB color space using an NSColorSpace object first, then you can get the components using the various NSColor accessor methods

Birnbaum answered 28/3, 2013 at 13:20 Comment(3)
This won't work either because the color is not in an RGB colorspace. You'd have to convert it first, using colorUsingColorSpaceName:.Zinnia
Yep, this crashes the app.Krever
Thanks the solution in full is: NSColor *testColor = [[NSColor colorWithCalibratedWhite:0.65 alpha:1.0] colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];Krever
L
12

Extracting RGBA values from NSColor: (Swift 3)

let nsColor: NSColor = .red
let ciColor: CIColor = .init(color: nsColor)!
print(ciColor.red) // 1.0
print(ciColor.green) // 0.0
print(ciColor.blue) // 0.0
print(ciColor.alpha) // 1.0 // Or use nsColor.alphaComponent

NOTE: NSColor.blackColor().redComponent will crash the app, but the above code won't

Lindbom answered 6/12, 2015 at 8:42 Comment(0)
C
9

I had the same problem when I wanted to convert a picked color to hexadecimal. NSColor components values was not correct. I managed to resolve my problem with your comment above.

Example in Swift:

let colorTest = NSColor.init(calibratedWhite: 0.65, alpha: 1.0)
let color = colorTest.usingColorSpace(NSColorSpace.deviceRGB) ?? colorTest
print(colorTest)
// NSCalibratedWhiteColorSpace 0.65 1
print(colorTest.colorSpace) 
// Generic Gray colorspace
print("red: \(color.redComponent) green:\(color.greenComponent) blue:\(color.blueComponent)") 
// red: 0.708725869655609 green:0.708725869655609 blue:0.708725869655609
Chitchat answered 21/7, 2017 at 9:56 Comment(0)
B
8

You need to convert the color to an RGB color space using an NSColorSpace object first, then you can get the components using the various NSColor accessor methods

Birnbaum answered 28/3, 2013 at 13:20 Comment(3)
This won't work either because the color is not in an RGB colorspace. You'd have to convert it first, using colorUsingColorSpaceName:.Zinnia
Yep, this crashes the app.Krever
Thanks the solution in full is: NSColor *testColor = [[NSColor colorWithCalibratedWhite:0.65 alpha:1.0] colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];Krever
E
4

For a NSColor * color

CGFloat red = [color redComponent];
CGFloat green = [color greenComponent];
CGFloat blue = [color blueComponent];
Ebb answered 28/3, 2013 at 13:22 Comment(3)
I'm afraid this crashes the app, since the color initialized is not in the RGB colorspace.Krever
Did you set the colorspace: NSColorSpace *sRGB = [NSColorSpace sRGBColorSpace]; and then create the NSColor in that space?Ebb
You should edit your answer, because not setting the colorSpace will cause a crash.Brolly
N
2

I have used this in the past, and it worked for me.

    NSColorSpace *colorSpace = [NSColorSpace sRGBColorSpace];
    NSColor *testColor = [NSColor colorWithColorSpace:colorSpace components:SRGB];

    CGFloat red = [testColor redComponent];

    CGFloat green = [testColor greenComponent];

    CGFloat blue = [testColor blueComponent];
Numbat answered 28/3, 2013 at 13:23 Comment(1)
I'm afraid this crashes the app, since the color initialized is not in the RGB colorspace.Krever
E
0

You have to check the colorspace first

then if it's rgb you can use

CGFloat red = [testColor redComponent];
...

For grayscale you have to convert it differently

CGFloat red = [testColor whiteComponent];
CGFloat blue = [testColor whiteComponent];
CGFloat green = [testColor whiteComponent];
Ecotone answered 28/3, 2013 at 13:29 Comment(0)
D
0

Here’s a safe Swift 5 SKColor extension for getting the RGB components of an NSColor or UIColor. (Note SKColor is just a typealias for one or the other based on the platform.)

public extension SKColor {
    var sRGBAComponents: (red: CGFloat , green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        #if os(iOS)
        let rgbColor = self // lolz no color conversion on iOS, but on iOS it'll respond to getRed(...) anyhow
        #elseif os(macOS)
        let rgbColor = usingColorSpace(.extendedSRGB) ?? SKColor(red: 1, green: 1, blue: 1, alpha: 1) // will return 'self' if already RGB
        #endif

        var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
        rgbColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        return (red: red, green: green, blue: blue, alpha: alpha)
    }
}
Debrief answered 19/5, 2020 at 23:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.