为什么Delphi报告的PPI与计算的不一样?

问题描述 投票:0回答:2

我使用 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 screen delphi-10.3-rio ppi
2个回答
2
投票

操作系统PPI

没有错误,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);

为什么需要使用虚拟操作系统 PPI 而不是硬件 PPI?

首先,不同的显示设备具有不同的硬件像素密度。例如,分辨率为 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 而不是一般的虚拟 PPI 显示文本数据和其他相关尺寸。

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

PixelsPerInch
- 一般 PPI 计算。

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

PixelsPerInch
值正确缩放字体。


0
投票

要扩展您的应用程序,您可以在设计时设置(对象检查器) 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;
© www.soinside.com 2019 - 2024. All rights reserved.