3

Apple 最近在 OS X 上启用了 30 位颜色支持。他们发布了一些示例代码来展示如何启用此功能。但是,它们似乎没有提供一个示例来说明如何检测您的应用程序何时在支持 30 位颜色的显示器上运行。

我们希望能够检测显示器何时支持 30 位颜色,并且只为支持它的显示器启用 30 位颜色,否则恢复为 24 位颜色。

有谁知道这是怎么做到的吗?

到目前为止,我已经尝试使用CGDisplayAPI (CGDisplayCopyDisplayModeCGDisplayModeCopyPixelEncoding) 来查询显示器的像素编码。但这些似乎总是返回 24 位编码,并且CGDisplayModeCopyPixelEncoding在 Mac OS X 10.11 中已被弃用。我也尝试过使用NSScreen’s“深度”属性,但这也返回每像素 24 位。

内置的系统信息应用程序显然能够获取这些信息,我只是不知道他们是如何做到的。有什么提示吗?

4

3 回答 3

1

从 macOS 10.12 开始,Apple 提供了一些新的 API,可让您检测显示器是否支持广色域(即深色)。有几种方法可以做到这一点:

  1. 使用 NSScreen 的- (BOOL)canRepresentDisplayGamut:(NSDisplayGamut)displayGamut

    NSArray<NSScreen *> * screens = [NSScreen screens];
    BOOL hasWideGamutScreen = NO;
    
    for ( NSScreen * screen in screens )
    {
        if ( [screen canRepresentDisplayGamut:NSDisplayGamutP3] )
        {
            hasWideGamutScreen = YES;
            break;
        }
    }
    
  2. 使用CGColorSpaceIsWideGamutRGB(...)

    hasWideGamutScreen = CGColorSpaceIsWideGamutRGB( screen.colorSpace.CGColorSpace );
    
  3. NSWindow也有- (BOOL)canRepresentDisplayGamut:(NSDisplayGamut)displayGamut

我不知道当显示器被认为是“宽色域 RGB”或能够时,您是否可以保证使用 30 位显示器NSDisplayGamutP3,但这似乎是 Apple 确定显示器是否能够宽屏的官方方式色域颜色。

于 2016-12-02T03:19:53.680 回答
0

有各种不好的选择。

首先,如果你记录一个显示模式(即 cast toid和 pass to NSLog(@"%@", ...)),你会发现真正的像素编码在那里。这很有趣,但你真的不想解析那个描述。

如果你(__bridge CFDictionaryRef)@{ (__bridge NSString*)kCGDisplayShowDuplicateLowResolutionModes: @YES }作为 options 参数传递给CGDisplayCopyAllDisplayModes(),你会发现你得到了一堆额外的显示模式。此密钥记录在标题中,但未记录在参考文档中。对于 Retina 显示器,一些额外的模式是未缩放显示模式的 2 倍缩放对应物。其他是 30 位伪装成 24 位模式的 24 位对应物。这些在您可以通过 API 查询的所有方面都是相同的,但日志记录显示了差异。(顺便说一句,尝试切换到其中一种模式将会失败。)

我认为,但您必须验证,除了支持 30 位颜色的显示器外,您不会获得这对看似相同的模式。

您也许可以从 IOKit 获取信息。您必须使用已弃用的函数来获取表示 GPU 显示对CGDisplayIOServicePort()的对象的服务端口。IOFramebuffer然后,您可以使用IORegistryEntrySearchCFProperty()搜索服务平面中的包含层次结构来查找具有“display-bpc”或“display-pixel-component-bits”等属性的对象并获取其值。至少,在我能够测试的几个系统上存在这样的对象和属性,尽管它们都使用 AMD GPU,并且该属性位于 AMD 特定的对象上,因此它可能不可靠。

最后,您可以启动一个子流程来运行system_profiler -xml SPDisplaysDataType并使用 property-list-serialization API 从生成的 XML 构建一个属性列表对象。然后,您可以在其中找到信息。您可以通过_spdisplays_display-vendor-idCGDisplayVendorNumber()_spdisplays_display-product-id和匹配找到相关显示CGDisplayModelNumber()。然后,深度在 key 下,其中的值表示 30 位颜色。_spdisplays_display-serial-numberCGDisplaySerialNumber()spdisplays_depthCGSThirtyBitColor

您还应该向 Apple 提交错误报告,要求以合理的方式执行此操作。

于 2016-04-28T03:03:08.747 回答
-1

对我有用的是传递depthLimitmy NSWindowto的属性NSBitsPerPixelFromDepth并检查返回值是否大于 24。警告:我只有两台 iMac 可以测试,一台是 2012 年的,另一台是 2017 年的,它们都在运行 High Sierra。

于 2018-01-26T20:44:13.333 回答