【问题标题】:Why PPI reported by Delphi is different from the calculated one?为什么德尔福报告的PPI与计算出来的不一样?
【发布时间】:2022-01-20 15:10:06
【问题描述】:

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

the formula计算,我的屏幕有142 ppi。 (实际值是:15.5" 对角线和 1920 x 1080 分辨率)。但是当我在 Delphi 中读取 Screen.PixelsPerInch 属性时,我得到 134 !这个值是我创建的每个 TFormPixelsPerInch 属性中报告的. 那么,为什么会有这种差异,哪个是真正的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?听起来像一个错误,如果尚未报告,您应该 report to Embarcadero
  • @RemyLebeau 我用的是 Delphi 10.3 Rio... 你能在其他 Delphi 版本中得到真正的价值吗?
  • @MarcusGradinaru 我没试过。
  • 你的计算给了我 72 ppi 的 528x298 毫米显示 1920x1080 像素。 Delphi 7 的 Screen.PixelsPerInch 报告 96。
  • 我想我解决了这个问题...Screen.PixelsPerInch 不会报告屏幕的真实 ppi,而是由您的窗口缩放设置缩放的标准 96 ppi。我将窗口缩放设置为 140%。所以,96 x 1.4 = 134 ppi...

标签: delphi screen delphi-10.3-rio ppi


【解决方案1】:

操作系统PPI

没有错误,Delphi 在PixelsPerInch 中返回正确的值。

PPI OS 会返回用于缩放你的应用程序的不是实际显示设备的实际 PPI 值,而是虚拟像素密度。

对于开发应用程序,您需要的 PPI 值是操作系统为您提供的值,而不是显示设备的实际 PPI 值。

您需要知道的一切都是操作系统的基线 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);

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

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

但是,如果您使用默认的 Windows 缩放设置 (100%),则当您运行 Windows 时,两个显示器的返回值将是 96 像素。显然,该值与这些硬件 PPI 值中的任何一个都不匹配,并且大约接近。

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

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

由于可以调整虚拟 PPI,因此在编写通用应用程序时了解实际的硬件 PPI 几乎没有用处。对于 DTP 和类似的应用程序,有时能够以 1:1 的比例查看设计是有价值的,但在这种情况下,人们通常使用硬件密度与操作系统匹配的监视器,或者用户必须能够输入他的硬件配置,并且该值是用于计算需要精确匹配物理尺寸的像素尺寸。

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

字体 PPI

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

Delphi 当前不支持自定义字体 PPI 值。也就是说,如果您将字体大小设置为 10 pt,则字体的实际像素高度将根据PixelsPerInch - 通用 PPI 计算。

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

【讨论】:

  • 是的,我明白了。我现在看到的唯一问题(你也看到了)是 Delphi 不支持自定义字体 PPI 值。如果我选择以不同的 PPI 值缩放我的表单,而不是 OS PPI,Font.Size 将使用 OS PPI 和字体大小...假设 14 与 14 的物理高度不同基线 PPI 上的字体大小。
  • 如果你想处理不同的比例,你需要手动调整字体大小。此外,即使 Delphi 支持单独的字体 PPI,它仍将基于操作系统提供的比例,而不是您选择的某些自定义值。除非您有一些非常具体的原因,否则您的应用程序应该使用操作系统提供的值,而不是您认为正确的比例。
  • 当然,正确的sling PPI是操作系统返回的。但即使我在 OS PPI 上缩放我的表单,如果 Font.PixelsPerInch 未设置为物理屏幕 PPI,则不会正确计算 Font.Size。对我来说,“正确的字体大小”意味着相同的大小必须对应相同的物理高度,而不管屏幕 PPI 是多少。我认为这就是它被引入的原因,所以我们可以控制每个显示器上的字体高度大小。否则我们可以直接以像素为单位指定字体大小...
  • "如果 Font.PixelsPerInch 未设置为物理屏幕 PPI,则不会正确计算 Font.Size" 这不是真的。 Font.Size (pt) 也是虚拟尺寸,它不遵循物理印刷尺寸。换句话说,在两台显示器(22 英寸和 24 英寸)上,默认的 Windows 字体大小为 9 pt 大小(以像素为单位)将是相同的(前提是两台显示器具有相同的分辨率和比例)。如果您尝试根据硬件 PPI 计算字体大小,您将得到错误的结果 - 不是用户想要或需要的。
  • 唯一的例外是如果用户自定义字体比例不是 100%,并且您想在字体上使用该自定义比例,但再次使用它也不会匹配物理大小。
猜你喜欢
  • 1970-01-01
  • 2022-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多