我使用 Delphi 10.3 Rio,需要知道屏幕 PixelsPerInch 比率以相应地缩放我的应用程序。
用公式计算,我的屏幕有142 ppi。 (实际值为:15.5 英寸对角线和 1920 x 1080 分辨率)。但是当我在 Delphi 中读取
Screen.PixelsPerInch
属性时,我得到 134!并且这个值也在我创建的每个 PixelsPerInch
的 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;
没有错误,Delphi 在
PixelsPerInch
中返回正确的值。
PPI OS为了缩放你的应用程序而返回的不是实际显示设备的实际PPI值,而是虚拟像素密度。
开发应用程序时,您需要的 PPI 值是操作系统给您的 PPI 值,而不是显示设备的实际 PPI 值。
您需要了解的一切是操作系统的基线 PPI 和当前 PPI 或比例因子。使用这些数字,您可以根据某个基线像素值计算缩放像素数。
例如,如果您的控件基线宽度为 100 像素,屏幕比例为基线 PPI 的 150%,则运行时控件大小将为 150 像素。
不同的操作系统有不同的基线 PPI。
操作系统 | 基线 PPI |
---|---|
Windows | 96 PPI |
macOS | 72 PPI |
安卓 | 160 PPI |
iOS | 163 PPI |
计算:
ScaledPx := MulDiv(Px, PixelsPerInch, BaselinePixelsPerInch);
ScaledPx := Px * ScaleFactor;
在 Windows 上:
ScaledPx := MulDiv(Px, PixelsPerInch, 96);
首先,不同的显示设备具有不同的硬件像素密度。例如,分辨率为 1920x1080 像素的全高清显示器将根据设备尺寸是 22 英寸还是 24 英寸而具有不同的硬件 PPI。第一个的 PPI 为 100.13,第二个的 PPI 为 91.79。
但是,当您运行 Windows 时,如果您使用默认的 Windows 比例设置 (100%),则两个显示器返回的值将为 96 像素。显然,该值与这些硬件 PPI 值都不匹配,并且近似接近。
因此,在两台显示器上显示 100 像素的正方形将导致该正方形的物理尺寸不同。
接下来,用户可以选择不同的比例设置。有人可能想使用 125% 比例,即 120 PPI。如果您在应用程序中使用实际的硬件 PPI,对于这样的用户来说,一切都太小了。
由于虚拟 PPI 可以调整,因此在编写通用应用程序时了解实际硬件 PPI 的用处很小。对于 DTP 和类似的应用程序,有时能够看到 1:1 比例的设计是有价值的,但在这种情况下,人们通常使用硬件密度与操作系统相匹配的显示器,或者用户必须能够输入他的硬件配置,该值是用于计算需要精确匹配物理尺寸的像素尺寸。
虽然有操作系统 API 可以为您提供显示设备的实际硬件 PPI,但在跨平台的许多设备上,由于各种原因,您将很难获得正确的 PPI 值。
除了一般的虚拟PPI之外,还有一个可以由用户独立定制的PPI值——字体PPI。字体比例的基线与不同平台上虚拟 PPI 的基线相同。完全尊重用户设置的应用程序将根据字体 PPI 而不是一般的虚拟 PPI 显示文本数据和其他相关尺寸。
Delphi 目前没有内置对自定义字体 PPI 值的支持。换句话说,如果您将字体大小设置为 10 pt,则字体的实际像素高度将根据
PixelsPerInch
- 一般 PPI 计算。
如果用户字体比例设置为 100%(这是最常用的值),那么 Delphi 将根据
PixelsPerInch
值正确缩放字体。
要扩展您的应用程序,您可以在设计时设置(对象检查器) Form1.Scaled 为 False,然后在运行时使用手动设置的内容按自定义因子缩放表单:
const DefaultDesignTimePPI = 96;
procedure TForm1.FormCreate(Sender: TObject);
begin
AutoScroll := false; // to resize the form window when scaling
ChangeScale(Screen.PixelsPerInch, DefaultDesignTimePPI);
Scaled := true;