为什么Delphi报告的PPI和计算出来的不一样?

Why PPI reported by Delphi is different from the calculated one?

我使用 Delphi 10.3 Rio,并且需要知道屏幕 PixelsPerInch 比率以相应地缩放我的应用程序。

the formula 计算,我的屏幕有 142 ppi。 (实际值是:15.5" 对角线和 1920 x 1080 分辨率)。但是当我在 Delphi 中读取 Screen.PixelsPerInch 属性 时,我得到 134 !这个值是在 [=13 中报告的=] 属性 我也创建了每个 TForm。那么,为什么会有这种差异,哪个才是真正的 ppi?

AIDA64 报告了 142 ppi 的实际值...所以我认为 Delphi 中的每英寸像素比有问题...

编辑:

我设法用这段代码获得了真正的 PPI...但我无法在每个 Delphi 组件中更改它。所以,如果我在我的组件中使用这个值,我会不会把一切都搞砸了?

procedure TForm1.FormCreate(Sender: TObject);
var PhiW, PhiH, PixW, PixH: Integer;
    DC: HDC;
    PhiD, PixD, PPI: Real;
begin
 DC:= Form1.Canvas.Handle;
 PhiW:= GetDeviceCaps(DC, HORZSIZE);
 PhiH:= GetDeviceCaps(DC, VERTSIZE);
 PixW:= GetDeviceCaps(DC, HORZRES);
 PixH:= GetDeviceCaps(DC, VERTRES);
 PhiD:= (Sqrt((PhiW*PhiW)+(PhiH*PhiH)))/25.4;
 PixD:= Sqrt((PixW*PixW)+(PixH*PixH));
 PPI:= PixD / PhiD;
 Label1.Caption:= IntToStr(Round(PPI))+' ppi';
end;

操作系统 PPI

PixelsPerInch.

中Delphi return没有错误和正确的值

PPI OS 将 return 用于缩放您的应用程序的目的不是实际显示设备的实际 PPI 值,而是虚拟像素密度。

对于开发应用程序,您需要的 PPI 值是 OS 给您的值,而不是显示设备的实际 PPI 值。

您需要知道的一切都是 OS 的基线 PPI 和当前 PPI 或比例因子。使用这些数字,您可以根据一些基线像素值计算缩放像素的数量。

例如,如果您的控件基线宽度为 100 像素并且屏幕比例为基线 PPI 的 150%,那么您的运行时间控件大小将为 150 像素。

不同的操作系统有不同的基准 PPI。

OS Baseline PPI
Windows 96 PPI
macOS 72 PPI
Android 160 PPI
iOS 163 PPI

计算:

ScaledPx := MulDiv(Px, PixelsPerInch, BaselinePixelsPerInch);

ScaledPx := Px * ScaleFactor;

在 Windows:

ScaledPx := MulDiv(Px, PixelsPerInch, 96);

为什么需要使用虚拟 OS PPI 而不是硬件 PPI?

首先,不同的显示设备具有不同的硬件像素密度。例如,分辨率为 1920x1080 像素的全高清显示器将具有不同的硬件 PPI,具体取决于设备尺寸是 22" 还是 24"。第一个将具有 100.13 PPI,第二个将具有 91.79 PPI。

但是如果您使用默认 Windows 比例设置 (100%),当您 运行 Windows 为两个显示器编辑的值 return 将是 96 像素。显然,该值与这些硬件 PPI 值都不匹配,只是近似接近。

因此在两个显示器上显示 100 像素的正方形会导致该正方形的物理尺寸不同。

接下来,用户可以选择不同的比例设置。有人可能想使用 125% 比例,即 120 PPI。如果你在你的应用程序中使用实际的硬件 PPI,对于这样的用户来说,一切都太小了。

因为虚拟PPI是可以调整的,知道实际的硬件PPI在编写通用应用程序时用处不大。对于 DTP 和类似应用程序,有时能够以 1:1 比例查看设计是有价值的,但在这种情况下,人们通常使用硬件密度与 OS 匹配的显示器,或者用户必须能够输入他的硬件配置,该值用于计算需要准确匹配物理尺寸的像素尺寸。

虽然有 OS API 可以为您提供显示设备的实际硬件 PPI,但由于各种原因,在跨平台的许多设备上您将很难获得正确的 PPI 值。

字体 PPI

除了一般的虚拟PPI,还有一个PPI值可以由用户独立自定义——字体PPI。字体比例的基线与不同平台上虚拟 PPI 的基线相同。完全遵守用户设置的应用程序将根据字体 PPI 而不是一般的虚拟 PPI 显示文本数据和其他相关尺寸。

Delphi 目前没有内置对自定义字体 PPI 值的支持。换句话说,如果您将字体大小设置为 10 pt,则字体的实际像素高度将根据 PixelsPerInch - 一般 PPI 计算。

如果用户字体比例设置为 100%(这是最常用的值),那么 Delphi 将根据 PixelsPerInch 值正确缩放字体。