문제

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?

도움이 되었습니까?

해결책 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

다른 팁

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)
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top