teddy
teddy

Reputation: 197

NSColor show different color in the screen

I extend NSColor to add class method

+ (NSColor*) initWithHTMLString: (NSString*) rgb

I set the background color for a NSWindow object:

[self.window setBackgroundColor:[NSColor initWithHTMLString:@"37854F"]]
NSLog(@"Color=%@",[self.window.backgroundColor toHTMLRGB]);

When I run the program, the log line is "Color=37854F". However, I use the tool PixelStick to drop the color pixel, the pixel color is not 37854F, the color component is little smaller than its origin.

Are there any people know the solution?

Upvotes: 0

Views: 820

Answers (2)

Matt Comi
Matt Comi

Reputation: 657

This is how you init an NSColor with an exact screen color (Swift 3):

let components = [red, green, blue, alpha]

let color = NSColor(
    colorSpace: NSScreen.main()!.colorSpace!, 
    components: components,
    count: 4)

If you color-pick a screenshot you can confirm that the RGB components match exactly.

Upvotes: 0

Mike Lischke
Mike Lischke

Reputation: 53337

The reason for the difference is that colors created with obj-c are adjusted to take the current color profile into account (see system preferences -> Monitors -> Colors). This goes so far that the same color appears differently when you have several monitors and drag your running application from one monitor to the other. Unfortunately, it's extremely difficult to use an exact color on a particular monitor, even if you use colorWithDeviceRed:Green:Blue:Alpha instead colorWithCalibratedRed:Green:Blue:Alpha.

Color perception is a complex matter and various output devices play an important role, so no wonder there is no 1:1 mapping. But it should really be possible to create a color (say in a painting app or color management app, designer app etc.) and recreate the exact same color in Cocoa, if both run on the same monitor.

Interesting to note is here: when you have your colors in a design on OSX (be it an image in a browser or PDF file or whatever) and use its component values in a Windows app in a virtual machine (e.g. in Parallels Desktop) you can reproduce the exact color as any screen color picker shows.

[Update]: Since setting the system color profile to a generic one solves the color matching it might be worth thinking about creating an own generic color space in code as described in this technical Q&A

[Update]: I just found another NSColor message that looks like is what we both are looking for:

NSColor colorWithSRGBRed:green:blue:alpha

In a few tests I could see the color was exact. Unfortunately this message is only available on 10.7 and higher.

Upvotes: 2

Related Questions