我想知道 Mac OSX 下的物理屏幕尺寸。但是NSDeviceResolution
总是报错值(72),所以分辨率/dpi的计算结果是错误的。
在“About This Mac”里面,有一个 Mac 型号字符串,我的是“15-inch, Early 2011”。所以我想知道是否有办法(可能在 obj-c 中)读取该字符串,然后我可以将其用作物理屏幕尺寸。
任何帮助表示赞赏。
我想知道 Mac OSX 下的物理屏幕尺寸。但是NSDeviceResolution
总是报错值(72),所以分辨率/dpi的计算结果是错误的。
在“About This Mac”里面,有一个 Mac 型号字符串,我的是“15-inch, Early 2011”。所以我想知道是否有办法(可能在 obj-c 中)读取该字符串,然后我可以将其用作物理屏幕尺寸。
任何帮助表示赞赏。
您可以使用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"
东西看起来很狡猾,但却是CGDirectDisplayID
从NSScreen
.
上面汤米的回答非常好——我已经将它移植到了 Swift(供我自己使用)并在此处发布作为参考,但汤米的回答应该被认为是规范的。
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 个物理像素。