How do I get my Cocoa app to draw exactly the color specified by my designer in Sketch? - cocoa

My designer has specified a color to draw. When I try to draw that color in a Cocoa app, I get a resulting color that’s visibly different from the reference image as displayed by Sketch.app.
I made a small Cocoa app that draws a custom view. Here’s the interesting part of the code. Note that I am initializing the color in SRGB space.
class View: NSView {
override func drawRect(dirtyRect: NSRect) {
let components : [CGFloat] = [156.0/255.0, 0, 254.0/255.0, 1]
let color = NSColor.init(SRGBRed: components[0], green: components[1], blue: components[2], alpha: components[3])
color.setFill()
NSRectFill(self.bounds)
}
}
Here’s what it draws. (Nevermind the part about the cursor. And I removed the window shadow so it would be easier to review this side by side with other windows.)
And here’s the Sketch file portion:
Putting it all together, here’s a side by side of the Sketch file and the custom view, as well as Xscope loupe displaying the color value under the mouse cursor.
When hovering over Sketch file, I see this:
When hovering over my custom view, I see this:
You can see that the color value of the pixel under the black mouse cursor as read by Xscope is significantly different. The colors also look significantly different on my Retina Macbook Pro display, though interestingly, not so different in the captured screenshot PNG.
HOWEVER: so far, this was all done with default display settings and color profile “Color LCD” (the hardware is Retina Macbook Pro with its built-in display). When I manually change the display profile to “sRGB IEC61966-2.1” in OSX Settings app, and then sample the colors again with Xscope, you can see these sampled values:
And when sampling the custom view:
Most interestingly, you can see that the values sampled by Xscope on my custom view exactly match the specified values, and the color is also visually correct. But of course, I can’t make my users change their display profile.
My question: how do I make my custom view color exactly match the color in Sketch (both for visual inspection and when sampled with the Xscope loupe) with the default Color LCD display profile?

Just worked through this issue myself. Here's my process. Just tested on a Retina Macbook Pro.
Open Sketch.
Open Digital Color Meter (installed on OSX)
Switch to 'Display in Generic RGB'
In menu, ensure that 'View -> Display Values -> As Decimal`
Mouse over your color of the artwork in sketch and note the values (e.g. 0, 150, 200)
Use that value in Cocoa:
-(void)drawRect:(NSRect)dirtyRect {
[[NSColor colorWithCalibratedRed:0/255.0 green:150/255.0 blue:200/255.0 alpha:1] set];
NSRectFill(self.bounds);
}
This should work, as 'Generic RGB' is a device independent space equivalent to the 'calibrated' color space in Cocoa.

Related

Get current tint for Desktop Tinting in macOS 10.14 Mojave

I am trying to read the current value of the tint applied in macOS 10.14 Mojave, and subscribe to updates. The color will update with the background image when you are in Dark mode and the Graphite color accent is not selected.
I would expect to be able to read it from NSColor.windowBackgroundColor, but the stored color does not seem to change, despite changes to what is on screen.
If you mean the behind-window tint that is applied to the window background, there doesn't seem to be a way to get that since it's location dependent: drag your window over a light and a dark background and see how that shines through as you move your window. The actual color is computed by the window compositing system.
Since you refer the "stored color", if you mean the CGColor and notice that this doesn't change as you switch from light to dark mode or vice versa, you may need to explicitly set the appearance first:
let saved = NSAppearance.current()
NSAppearance.setCurrent(someView.effectiveAppearance)
// Here you can access the "true" colors (minus vibrancy/compositing effects):
let cgColor = NSColor.windowBackgroundColor.cgColor
NSAppearance.setCurrent(saved)
This is necessary when working outside a drawRect: method (which automatically sets up the current appearance for you).

Access Default Window Color Cocoa

I have an SKView with a picture of a keyboard in a window as shown below. I would like the background color of the SKScene it's presenting to be the same color as the window behind it, so that it would appear as if the keyboard was just in the window, and not in something else that was in the window. After consulting the NSColor documentation, I tried setting the background color of the SKScene as NSColor.windowBackgroundColor(). The color below is what I got. I'm assuming there was some kind of error and so it defaulted to black. That being said, how do I access the default color of a window?
Set the SKView's allowsTransparency to true and then set the SKScene's backgroundColor to NSColor.clearColor().
I think that using windowBackgroundColor() gives black if the view doesn't allow transparency and works if it does because it's effectively being translated to clearColor() by "accident". windowBackgroundColor() is a bit strange. It's not in either an RGB nor a gray-scale color space and it can't be converted to either of those. I'm guessing that SKScene tries to convert the background color to the RGB color space and, when that fails, it uses clearColor() as a fallback.

Color picker on mac os-x selects wrong colors

Our designer gave me a color value:
RGB 217,114,62
In mac image preview I open the color selector, switch to rgb and put in the rgb values. But the color preview seems to be too dark. So I take the color picker and select the color in the preview window. And instead of the same values, it shows RGB 206,93,48. First I thought some sort of color profile would change the colors. But reapeating the procedure with this darker color does not result in a third value. It stays 206,93,48. Then I guessed it might be the nearest web safe color that it switches to. But it's not in the list. What is going on here? Is 217,114,62 a magic value?
I decided to make a html page with a div and styled it to rgb 217,114,62.
All fine:
<body>
<div style="background: rgb(217,114,62);width:300px;height:300px;">RGB 217,114,62</div>
</body>
Now I made a screen shot and opened it in preview. Fine. I added a rectangle, selected it's color with the color picker. The correct color as you can see.
Then I just click the pointer into the HEX field. Automatically the rectangle darkens but the colour values stay the same. See:
When I now pick the darker color from the rectangle it is... You already guessed it... 206,93,48. WTF!?
I have the same problem in all my mac programs that use the color picker.
I have no clue what it can be. I tried changing the display color settings to whatever. Same result. OS-X 10.10.1.
You (and possibly your designer) need to familiarize yourself with color profiles. "RGB 217,114,62" does not adequately specify a color. You would need to know in which color profile that was expressed. For example, sRGB vs. Generic RGB.
When you use the eyedropper in the color picker to sample a color from the screen, you get the values in the device color profile. This will be different from a calibrated color profile like sRGB or generic.
The gear icon next to the pop-up menu showing "RGB" in your screenshots both shows you the color profile for the values shown by the sliders and text fields and lets you change the profile (thus converting the values).
I suspect that clicking in the hex field switches the color profile to sRGB because that's the color profile of web colors but, on the theory that you want to use the sliders and text fields to specify a color in that profile, it doesn't convert the current values. Instead, it reinterprets them in the new profile. For what it's worth, your last screenshot as shown on my screen and sampled with the eyedropper shows that the outer color is nearly 217,114,62 in the Generic RGB color profile while the inner color is nearly 217,114,62 in the sRGB color profile.
You need to check with your designer to find out what color profile they are expressing the colors in. If they aren't color-profile-savvy, they may have expressed them in their personal screen's device profile, which is basically useless. Also, if they are giving you image files to work from, those need to have an embedded color profile so that you can be sure they display (nearly) the same on your screen as they do on theirs. (You both should also calibrate your display's color profile using Display Calibrator or dedicated hardware. You can open Display Calibrator from System Preferences > Displays > Color > Calibrate.)
Once you've confirmed that, you need to switch the color picker to the desired color profile before entering values. Or sample from an image file with an embedded color profile as displayed by an app which properly handles that (Preview will do), and then convert to a specific color profile. If you were to create the color in code, you would use +[NSColor colorWithCalibratedRed:green:blue:alpha:] for values in the Generic RGB color space or +[NSColor colorWithSRGBRed:green:blue:alpha:] for values in the sRGB color space.

Wrong color in Interface Builder's color picker

I have an UIImageView with a brown image that will not always reach the top part. The UIImage view is inside a white UIView.
So, because the top part of the image is a linear brown color, I said I will make the UIView underneath it the same brown color, and the user will not see where the image ends. So far, so good.
My problem is, when I pick the color in the top part of the image, the color picker picks a more darker color than actually is there :(
Before I click the color picker:
After I click the color picker:
How comes ?
Just wanted to elaborate upon the accepted answer with some screenshots.
If you want to match RGB values between Photoshop and Xcode exactly (without conversion between colorspaces) then you need to save your images in generic RGB and enter any dropper values using the generic RGB colorspace.
When you choose "Save for Web & Devices" from Photoshop, uncheck the "Convert to sRGB" box.
In Xcode, click the colorspace popup in the color picker and choose "Generic RGB", then enter the red, green and blue values from Photoshop, NOT THE HEX VALUE as this reverts back to the sRGB colorspace for some reason (be careful not to tab to the hex field either, as that also changes the colorspace to sRGB).
More info here, including how to match screenshots.
I've managed to find out a solution/explanation (tho I'm still confused) in this answer: https://stackoverflow.com/a/9203647/460750
Basically, what I did to solve my issues, was to choose from the RGB "types" select (that little square under the color picker) the Apple RGB option, and enter the R, G and B values manually, instead of using the picker.
Odd...
Its because the component numbers don’t spec a color. We also need to know the color space which xCode uses. Colorspace which encodes or decodes is available in the drop down left to the RGB slider.
By default xCode chooses the "Generic RGB" and that is what UIColor uses spec color from RGB. If we use magnifying glass, it will change to "Device RGB” space and that is based on your current screen.
So “sRGB" or "Adobe RGB" would be the better or close to what you want if you are using the magnifying glass to pick a color.
I think Generic RGB also works.
the trick is you need to enter number of R G B manually
after change the RGB mode in dropdown list
Odd... (too)
UPDATE 10.10.4
I had this issue as well, I reported it to Apple, and it seems to have been solved on 10.10.4 (it was related to the color picker itself, not to Xcode/IB)
Can someone else confirm it?
This is an old question, but it was important for me to add some info.
The only method that has been working for me accurately over the years was to not use PS's Color Picker, but use macOS' built-in "Digital Color Meter".
It's bundled with every installation of macOS and the RGB values emitted from there with "Generic RGB" always reproduce the correct color in Xcode Storyboards.

How do I create NSColor instances that exactly match those in a Photoshop UI mockup?

My UI designer gives me great UI mockups created in Photoshop. I want to exactly match the colors in the mockup, but every time I create a color using the -colorWithCalibratedRed:green:blue:alpha: method of NSColor, the colors do not match.
I have tried sampling the colors from the Photoshop mockup using the Pixie app in /Developer/Applications/Graphics Tools/ and it copies an NSColor definition to the clipboard, but these colors are not correct when I build and run the app.
If I use the values that the Photoshop color picker provides, they are not correct either.
I suspect this must be something to do with the fact that I'm sampling a calibrated color from the screen and so the values are incorrect, but I am not sure how to work around this.
If I use -colorWithDeviceRed:green:blue:alpha: and pass through the values it looks correct, but then the color is not consistent on other systems.
Is there a way to do this reliably?
There's no such thing as a "pure" RGB color that's consistent from one display to the next. Unless you're working in a standardized color space, the numbers that show up for a color on one display will probably render slightly differently on another.
Have your designer convert your mock-ups to a standard color space such as sRGB. Then you can use the methods on NSColor that take not just component values but the color space the components are in; this will get you colors that should look similar on any display.
In other words, a color swatch made from (R, G, B) = (1.0, 1.0, 1.0) in Photoshop using sRGB should look virtually identical to a color swatch drawn using a color you get this way:
NSColorSpace *sRGB = [NSColorSpace sRGBColorSpace];
CGFloat components[3] = { 1.0, 1.0, 1.0 };
NSColor *sRGBRed = [NSColor colorWithColorSpace:sRGB components:&components count:3];
Note though that +[NSColorSpace sRGBColorSpace] is only available on Mac OS X 10.5 Leopard and above. If you still need to run on Tiger, you could write a little utility app that runs on 10.5 and converts the canonical sRGB colors to the calibrated RGB space:
NSColor *calibratedColor = [sRGBRed colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
Regardless of whether you use sRGB or the calibrated space, once you have a set of colors, you could put them in an NSColorList that you write to a file and then load from your application's resources at runtime.
Have you tried turning color management off in Photoshop? With color management enabled, the actual RGB pixel values displayed and the ones reported by Photoshop may not be the same.
Thanks, I just tried creating a test PSD with pure RGB values and I also created a simple app with a view that displays [NSColor redColor], [NSColor greenColor] and [NSColor blueColor].
When I sample the PSD (opened in Photoshop or Preview), Pixie shows me pure values (e.g R:255 G:0 B:0 for red) but when I sample my app it shows non-pure colors e.g (R:253 G:2 B:30) for the [NSColor redColor]. I get the same result if I use [NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] instead of [NSColor redColor].

Resources