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

时间:2012-09-25 18:44:22

标签: objective-c macos screen dpi

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

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

感谢任何帮助。

2 个答案:

答案 0 :(得分: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"事情看起来很狡猾,但CGDirectDisplayIDNSScreen获得{{1}}。{/ p>

答案 1 :(得分:0)

汤米(Tommy)的回答非常好-我已将其移植到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/72英寸” 也定义为“无论1 x 1个单位的盒子的宽度或高度最终以当前分辨率出现在当前显示器上-两个定义通常彼此冲突。)

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