Pergunta

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?

Foi útil?

Solução 3

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

Outras dicas

Extracting RGBA values from NSColor: (Swift 3)

let nsColor:NSColor = NSColor.red
let ciColor:CIColor = CIColor(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

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

For a NSColor * color

CGFloat red = [color redComponent];
CGFloat green = [color greenComponent];
CGFloat blue = [color blueComponent];

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

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

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)
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top