Macos NSColor在屏幕上显示不同的颜色

Macos NSColor在屏幕上显示不同的颜色,macos,cocoa,Macos,Cocoa,我扩展了NSColor以添加类方法 + (NSColor*) initWithHTMLString: (NSString*) rgb 我为NSWindow对象设置了背景色: [self.window setBackgroundColor:[NSColor initWithHTMLString:@"37854F"]] NSLog(@"Color=%@",[self.window.backgroundColor toHTMLRGB]); 当我运行程序时,日志行是“Color=37854F”。但是

我扩展了NSColor以添加类方法

+ (NSColor*) initWithHTMLString: (NSString*) rgb
我为NSWindow对象设置了背景色:

[self.window setBackgroundColor:[NSColor initWithHTMLString:@"37854F"]]
NSLog(@"Color=%@",[self.window.backgroundColor toHTMLRGB]);
当我运行程序时,日志行是“Color=37854F”。但是,我使用PixelStick工具删除彩色像素,像素颜色不是
37854F
,颜色分量比其原点小一点


有人知道解决方案吗?

产生差异的原因是,使用obj-c创建的颜色会根据当前的颜色配置进行调整(请参见系统首选项->监视器->颜色)。这样,当您有多个监视器并将正在运行的应用程序从一个监视器拖动到另一个监视器时,相同的颜色会显示不同。不幸的是,在特定的显示器上使用精确的颜色是非常困难的,即使您使用带有设备的colorEd:Green:Blue:Alpha而不是带有校准的colorEd:Green:Blue:Alpha

颜色感知是一个复杂的问题,各种输出设备发挥着重要作用,因此难怪没有1:1映射。但如果两者都在同一台显示器上运行,那么创建一种颜色(比如在绘画应用程序或颜色管理应用程序、设计师应用程序等中)并在Cocoa中重新创建完全相同的颜色应该是完全可能的

这里值得注意的是:当您在OSX上的设计中使用颜色时(无论是浏览器中的图像还是PDF文件或其他文件),并在虚拟机的Windows应用程序中使用其组件值时(例如在Parallels Desktop中),您可以复制任何屏幕颜色选择器显示的精确颜色

[更新]:由于将系统颜色配置文件设置为通用配置文件可以解决颜色匹配问题,因此可能值得考虑在代码中创建一个自己的通用颜色空间,如本文所述

[更新]:我刚刚发现另一条NSColor消息,看起来就像我们都在寻找的:

NSColor colorWithSRGBRed:green:blue:alpha

在一些测试中,我可以看到颜色是准确的。不幸的是,此消息仅在10.7及更高版本上可用。

这就是使用精确屏幕颜色初始化NSColor的方式(Swift 3):


如果选择屏幕截图的颜色,可以确认RGB组件完全匹配。

什么是
到HTMLRGB
?您的
initWithHTMLString:
的代码是什么?PixelStick说它是什么颜色?另外,考虑“设备”和“校准”的颜色空间(参见文档中的颜色编程主题)指南。.@matt to htmlrgb formrat NSColor to NSString,initWithHTMLString:只需剪切两个字节并更改为unsigned int,使用colorWithcalibedred:green:blue:alpha:创建新的NSColor对象。@JoshuaNozzi您的评论给了我一点启发。我将阅读更多信息。谢谢。您的信息很有用,但不是我的情况。我的情况与您的情况相同我使用HTML RGB字符串,它是从Java程序中挑选出来的,放在我的Mac OS X程序中。当我运行两个应用程序(Java+Mac)时在同一个监视器中,它们是不同的。这就是我所说的。请再读一遍。您正在用Obj-C代码创建颜色,当它显示在屏幕上时,它的颜色与从中获取组件值的java程序的颜色不同。我们如何使NSColor与当前的显示配置文件独立?我认为colorWithDeviceId:Green:Blue:Alpha会做这项工作,但颜色永远不会完全匹配。所以我不知道。这就是为什么我在回答中写到了这些问题。谢谢你提供的信息。如果我选择通用RGB配置文件,颜色是相同的。但是用户可以选择另一个配置文件。我们如何知道现在选择了哪个配置文件?
let components = [red, green, blue, alpha]

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