我应该如何查询 Retina 硬件中的物理像素数?
How should I query the number of physical pixels in Retina hardware?
我正在寻找一种获取两条信息的方法:(1) 显示器的完整物理分辨率,即使它是 Retina 屏幕; (2) 操作系统将根据当前系统设置假装相同屏幕的分辨率。到目前为止,我能够得到 (2) 而不是 (1)。看来我 运行 反对 here
的评论
There is even more mess if somebody sets "Scaled" Resolution in macOS System Preferences->Displays
无法找到有关如何导航 "mess" 的任何信息。到目前为止,我有以下内容,我用 clang -framework Cocoa -x objective-c -o grokResolution
:
编译
#import <AppKit/AppKit.h>
void ReportRect(CGRect rect, const char *description)
{
printf("{'x': % 5g, 'y':% 5g, 'width':% 5g, 'height':% 5g, 'name':'%s'}\n",
rect.origin.x, rect.origin.y,
rect.size.width, rect.size.height,
description);
}
int main(int argc, char** argv)
{
NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
CGRect looksLike = [screen frame];
CGRect backing = [screen convertRectToBacking:looksLike];
ReportRect(looksLike, "looksLike");
ReportRect(backing, "backing");
printf("{'backingScaleFactor' : %0.2f}\n", [screen backingScaleFactor]);
}
我的 Retina 屏幕有 2560x1600 物理像素。如果我使用默认缩放设置(系统偏好设置应用程序使用 "Looks like 1280 x 800" 进行预览),则程序输出以下内容:
{'x': 0, 'y': 0, 'width': 1280, 'height': 800, 'name':'looksLike'}
{'x': 0, 'y': 0, 'width': 2560, 'height': 1600, 'name':'backing'}
{'backingScaleFactor' : 2.00}
所以这似乎是正确的。但是,如果我在系统偏好设置中单击右侧的下一个缩放设置,然后重新 运行 程序,我得到:
{'x': 0, 'y': 0, 'width': 1440, 'height': 900, 'name':'looksLike'}
{'x': 0, 'y': 0, 'width': 2880, 'height': 1800, 'name':'backing'}
{'backingScaleFactor' : 2.00}
现在,虽然系统偏好设置的 "looks like" 设置似乎正确反映在 [screen frame]
的输出中,但我对整个系统的理解显然存在缺陷,因为我预计 backingScaleFactor
and/or convertRectToBacking
正确地从假物理分辨率转换为真实物理分辨率。当系统首选项发生变化时,backingScaleFactor
似乎没有正确调整——在这种情况下,转换的像素比我的硬件实际拥有的像素多 returns。
如何正确转换?还是有另一种更直接的方法来查询显示器的实际物理像素数?
(我知道 system_profiler SPDisplaysDataType | grep Resolution
但我需要一个可以在现有 obj-C 源代码中运行的解决方案。)
比例因子总是整数。到目前为止,它始终是 1 或 2。有一天,Apple 可能会为 macOS 引入 3x 显示支持。
后备存储不一定对应于物理显示像素。对于某些 "scaled" 分辨率,后备存储 大于 物理显示像素的数量。然后按比例缩小以进行实际显示。这就是你的第二个例子的情况。
关于如何获得物理显示像素的数量,最近有几个问题对此进行了一些讨论,但没有确定的答案。请参阅 和评论中的链接。
我正在寻找一种获取两条信息的方法:(1) 显示器的完整物理分辨率,即使它是 Retina 屏幕; (2) 操作系统将根据当前系统设置假装相同屏幕的分辨率。到目前为止,我能够得到 (2) 而不是 (1)。看来我 运行 反对 here
的评论There is even more mess if somebody sets "Scaled" Resolution in macOS System Preferences->Displays
无法找到有关如何导航 "mess" 的任何信息。到目前为止,我有以下内容,我用 clang -framework Cocoa -x objective-c -o grokResolution
:
#import <AppKit/AppKit.h>
void ReportRect(CGRect rect, const char *description)
{
printf("{'x': % 5g, 'y':% 5g, 'width':% 5g, 'height':% 5g, 'name':'%s'}\n",
rect.origin.x, rect.origin.y,
rect.size.width, rect.size.height,
description);
}
int main(int argc, char** argv)
{
NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
CGRect looksLike = [screen frame];
CGRect backing = [screen convertRectToBacking:looksLike];
ReportRect(looksLike, "looksLike");
ReportRect(backing, "backing");
printf("{'backingScaleFactor' : %0.2f}\n", [screen backingScaleFactor]);
}
我的 Retina 屏幕有 2560x1600 物理像素。如果我使用默认缩放设置(系统偏好设置应用程序使用 "Looks like 1280 x 800" 进行预览),则程序输出以下内容:
{'x': 0, 'y': 0, 'width': 1280, 'height': 800, 'name':'looksLike'}
{'x': 0, 'y': 0, 'width': 2560, 'height': 1600, 'name':'backing'}
{'backingScaleFactor' : 2.00}
所以这似乎是正确的。但是,如果我在系统偏好设置中单击右侧的下一个缩放设置,然后重新 运行 程序,我得到:
{'x': 0, 'y': 0, 'width': 1440, 'height': 900, 'name':'looksLike'}
{'x': 0, 'y': 0, 'width': 2880, 'height': 1800, 'name':'backing'}
{'backingScaleFactor' : 2.00}
现在,虽然系统偏好设置的 "looks like" 设置似乎正确反映在 [screen frame]
的输出中,但我对整个系统的理解显然存在缺陷,因为我预计 backingScaleFactor
and/or convertRectToBacking
正确地从假物理分辨率转换为真实物理分辨率。当系统首选项发生变化时,backingScaleFactor
似乎没有正确调整——在这种情况下,转换的像素比我的硬件实际拥有的像素多 returns。
如何正确转换?还是有另一种更直接的方法来查询显示器的实际物理像素数?
(我知道 system_profiler SPDisplaysDataType | grep Resolution
但我需要一个可以在现有 obj-C 源代码中运行的解决方案。)
比例因子总是整数。到目前为止,它始终是 1 或 2。有一天,Apple 可能会为 macOS 引入 3x 显示支持。
后备存储不一定对应于物理显示像素。对于某些 "scaled" 分辨率,后备存储 大于 物理显示像素的数量。然后按比例缩小以进行实际显示。这就是你的第二个例子的情况。
关于如何获得物理显示像素的数量,最近有几个问题对此进行了一些讨论,但没有确定的答案。请参阅