如何读取OSX的物理屏幕大小?

问题描述 投票:14回答:2

我想知道Mac OSX下的物理屏幕尺寸。但NSDeviceResolution总是报告错误的值(72),因此resolution / dpi的计算结果是错误的。

在“关于这台Mac”里面,有一个Mac模型字符串,我的是“15英寸,2011年初”。所以我想知道是否应该有一种方法(可能是obj-c),读取该字符串然后我可以将其用作物理屏幕大小。

任何帮助表示赞赏。

objective-c macos screen dpi
2个回答
19
投票

您可以使用CGDisplayScreenSize以毫米为单位获取屏幕的物理尺寸。由此您可以计算DPI,因为您已经知道了分辨率。

所以例如

NSScreen *screen = [NSScreen mainScreen];
NSDictionary *description = [screen deviceDescription];
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
CGSize displayPhysicalSize = CGDisplayScreenSize(
            [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);

NSLog(@"DPI is %0.2f", 
         (displayPixelSize.width / displayPhysicalSize.width) * 25.4f); 
         // there being 25.4 mm in an inch

@"NSScreenNumber"事情看起来很狡猾,但是从explicit documented means获得CGDirectDisplayIDNSScreen


0
投票

汤米上面的回答非常好 - 我已将它移植到Swift(供我自己使用)并在此发布作为参考,但Tommy应该考虑规范。

import Cocoa

public extension NSScreen {
    var unitsPerInch: CGSize {
        let millimetersPerInch:CGFloat = 25.4
        let screenDescription = deviceDescription
        if let displayUnitSize = (screenDescription[NSDeviceDescriptionKey.size] as? NSValue)?.sizeValue,
            let screenNumber = (screenDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? NSNumber)?.uint32Value {
            let displayPhysicalSize = CGDisplayScreenSize(screenNumber)
            return CGSize(width: millimetersPerInch * displayUnitSize.width / displayPhysicalSize.width,
                          height: millimetersPerInch * displayUnitSize.height / displayPhysicalSize.height)
        } else {
            return CGSize(width: 72.0, height: 72.0) // this is the same as what CoreGraphics assumes if no EDID data is available from the display device — https://developer.apple.com/documentation/coregraphics/1456599-cgdisplayscreensize?language=objc
        }
    }
}

if let screen = NSScreen.main {
    print("main screen units per inch \(screen.unitsPerInch)")
}

请注意,返回的值实际上是“每英寸点数”(但不适用于所有定义;请参见下文),几乎从不“每英寸像素数” - 现代Mac的每点数量取决于当前的像素数“系统偏好设置”中的“分辨率”设置和设备的固有分辨率(Retina显示屏具有更多像素)。

您对返回值的了解是,如果您使用类似代码绘制一行

CGRect(origin: .zero, size: CGSize(width: 10, height: 1)).fill()

如果你用一个非常精确的尺子固定在屏幕上,那么这条线将是1 / pointsPerInch.height英寸高和1 / pointsPerInch.width英寸宽。

(很长一段时间以来,图形框架已将“点”定义为“现实世界中1/17英寸”,也称为“无论盒子的宽度或高度是1 x 1单位最终都是当前的监控当前的分辨率 - 两个通常相互冲突的定义。)

因此,对于这段代码,我使用“单位”这个词来表明我们不是处理1/72英寸,也不是1个物理像素。

© www.soinside.com 2019 - 2024. All rights reserved.