学习
实践
活动
工具
TVP
写文章
专栏首页walterlv - 吕毅的博客将 UWP 的有效像素(Effective Pixels)引入 WPF

将 UWP 的有效像素(Effective Pixels)引入 WPF

将 UWP 的有效像素(Effective Pixels)引入 WPF

发布于 2017-11-14 03:26 更新于 2017-11-14 04:49

在很久很久以前,WPF 诞生之初,有一个神奇的单位,它的名字叫做——设备无关单位(DIP,Device Independent Unit)。微软给它描绘了一片美好的愿景——在任何显示器上显示的尺寸是相同的。

What the ** is this unit!!! 神 TM 相同!!!

UWP 采用有效像素(Effective Pixels)来描述尺寸,这是才是能够自圆其说的一套尺寸描述;WPF 的尺寸机制与 UWP 完全就是同一套,使用有效像素才能解释 WPF 尺寸变化上的各种特性!


统一概念

在继续讨论之前,我们必须统一几个概念。不能说那些意义不明确的词,尤其是“宽高”“大小”“尺寸”“更大”。试想你说一个按钮的宽高是 200,那么它的宽高到底是多少呢?一个屏幕上的按钮和另一个屏幕上的按钮哪个更大呢?

在本文中,对于尺寸,我们只说三个概念:

  • 物理尺寸(单位:厘米)
  • 显示器像素个数(单位:个)
  • 有效像素(即 WPF 中最常用的那个单位;在本文结束之前,这应该是一个未定义的概念)

如果我们说 A 按钮比 B 按钮的物理宽度更大,那么无论它们显示在哪个显示器上,都具备相同的关系——因为我们可以拿尺子来量。

如果我们说 A 按钮比 B 按钮在宽度上占用的显示器像素个数更多,我们也可以拿放大镜去屏幕上一个点一个点地数——当然,各种截图工具已经在最佳分辨率下具备数像素个数的功能了(这里一定要突出最佳分辨率)。

而有效像素(Effective Pixels,本文记其为 epx)就是本文从 UWP 中引入的尺寸概念。当我们说按钮的有效像素宽度为 200 时,指的是你在 WPF 的 XAML 或 C# 代码中写下了 Width="200"

接下来,当我们谈论尺寸时,只会用以上三个概念进行比较,而不会再用模糊不清的尺寸名词。


从愿景看有效像素的意义

有效像素单位的诞生一定是为了解决某种尺寸问题,而且是因为现有的尺寸单位无法简单地描述这一问题。而我们就要准确描述这一问题,并将得到的单位定义成“有效像素”。

吐槽 DIP

WPF 曾经说自己用的是“设备无关单位”(DIP),愿景是在所有显示器上显示的物理尺寸相同。比如你在代码中写了 Width="96" 的按钮,那么在所有显示器上其尺寸为 1 英寸。

其实简单测试就不难发现这是一个根本无法自圆其说的愿景,具体无法自圆其说的点有两个。

  1. WPF 说自己的开发无需考虑 DPI 缩放,因为它会自己做缩放。那么当你写下 Width="96" 时,到底缩放还是不缩放呢?缩放就迁就了 DPI 缩放的特性,违背了物理尺寸相同的特性;不缩放就迁就了物理尺寸相同的特性,丢失了 DPI 缩放的特性。
  2. 在非 PC 设备(手机、平板电脑、大屏幕电视)上,如果依然保持物理尺寸相同,那么 PC 上显示合适的 3cm 的按钮在手机上将占据大半个屏幕,在电视上将小得几乎看不见。怎么能让一个 UI 框架做出这么脑残的设计呢?

有效像素(epx)的愿景

有效像素概念的出现,就摒除了 WPF 物理尺寸相同这样荒谬而无法自圆其说的设定。但为了给有效像素设下定义,我们来看看微软到底期望这样的尺寸单位带来哪些方便吧:

▲ 如果此处看不到视频,请前往 Channel 9 观看:Designing Universal Windows Platform apps

具体说来,对于手机和平板电脑(笔记本、Surface)这些近距离观看的设备,其物理尺寸可以更小;对于客厅摆放的大屏幕电视,观看距离较远,物理尺寸应该更大。相同的界面元素在不同设备上显示时,呈现出来的效果在视野角度上是相近的,这才是人眼观看比较舒适的尺寸概念的设计。

▲ 图片来自于微软 UWP 设计指导文档 Introduction to Universal Windows Platform (UWP) app design (Windows apps)

可以看出,有效像素的出现解决了我在 以上吐槽 中列举出无法自圆其说的第 2 点。认识到一个优秀的屏幕显示单位并不是按物理尺寸定义,而是根据不同的使用场景有所不同。第 1 点也部分得到了缓解——接受 DPI 缩放的特性,放弃承认物理尺寸相同的设定。

有效像素(epx)的局限性

一个好的概念除了要充分展示自己的愿景,也要看清自己的局限性。

而有效像素的局限性就在于——它的愿景只是理想状态下才能有的效果,而微软本身允许硬件厂商和用户进行设置以偏离理想状态。

具体是这样的:

  1. 显示器厂商为了自己的销售目标,会推出各种各样的型号——有高端的,有低端的,有主打性价比的。而性价比的主要来源就是——“噱头”——在部分参数上非常漂亮,部分参数却缩水严重。比如同样是 34 寸的 21:9 超宽屏显示器,5999 元的可以是 3440×1440 像素个数,而 3999 元的就只能是 2560×1080 像素个数。前者每英寸像素点数接近 96,而后者则低多了。Windows 操作系统上支持的最低 DPI 设置只能是 96 了,不能再低;以至于后者实际上在相同观看距离上比前者显示的界面元素的物理尺寸会大很多。这是硬件厂商的销售策略,你一个虚拟的单位还能拿它怎么样! 这其实是此愿景不能实现的最主要原因了——各大显示器厂商都存在不按照最佳观看效果设置显示器参数的问题。这也是为什么我们经常能发现有些笔记本上的图标和字体大小被默认设置得小得可怜,或者超大屏幕设备上文字小得远处看不清的原因。(这里我们只谈显示器厂商在 EDID 信息中设置的最佳时序,这个时序欺骗了操作系统使之给出了不合适的显示效果;不要说用户可以改的问题,毕竟让用户改已经提高了门槛了。)
  2. 用户可以随时修改屏幕显示分辨率,修改系统或屏幕的 DPI 值。在显示分辨率与显示器实际物理分辨率不一致的情况下,用户还能设置画面的填充方式(居中或是拉伸)。 我们认为,用户主动设置 DPI 是出于自己的一些目的——希望放大或缩小界面元素,而这有可能是因为原有大小对用户自己来说看起来不够舒适。(这里不想吐槽设置分辨率还不设置为居中显示的用户,那种画面模糊的感觉,怎么能承受!)

事实上,目前为止,只有一款设备真正达到了微软期望中的理想状态,那就是——Surface Studio!其它都只能算作接近,或者连接近都算不上。

给有效像素下个定义

结合微软对有效像素的愿景,结合实际情况,我认为“有效像素”的定义应该是这样的:

在理想状态下,1 有效像素等于用户观看距离 50cm 时,观看屏幕上 1/96 英寸的物理距离所对应的视角大小。 非理想状态下,1 有效像素等于显示器点对点显示像素时,1 屏幕像素乘以系统 DPI 值除以 96

WPF 和 UWP 的尺寸单位都可以用有效像素来理解,而这本身就是它们两个框架内建的单位系统。(彻底抛弃那个不能自圆其说的 DIP 吧!)

有效像素的特性

在以上定义之下,再研究有效像素的特性时,我们便能接受那些非理想状态下的不同行为,不再像 WPF 的 DIP 那样绝对而富有争议。

按钮的大小之争

当我们在代码中写下 Width="96" 时,这个按钮到底多大?

谈物理尺寸:

  • 在 Surface Studio 这样的理想设备上,如果用户没有胡乱设置,它的物理宽度是 1 英寸;
  • 在同一个显示器设备上,如果显示器的 PPI 是 96 pixels/inch,且用户使用最佳分辨率
    • DPI 值设置为 96,则它的物理宽度是 1 英寸
    • DPI 值设置为 144,则它的物理宽度是 1.5 英寸
    • DPI 值设置为 192,则它的物理宽度是 2 英寸
  • 在以上情况下,如果 DPI 值固定为 96,但用户降低了分辨率
    • 居中点对点显示,则它的物理宽度是 1 英寸
    • 拉伸显示,则它的物理宽度大于 1 英寸
  • 换一台显示器,PPI 值更大,则相同情况下的每一种情况都比以上物理宽度更小

谈显示器像素个数:

  • 用户使用了最佳分辨率
    • 在 DPI 值为 96 时,显示完按钮宽度所用的屏幕像素个数为 96
    • DPI 值设置为 192 时,则显示完按钮宽度所用的屏幕像素个数是 192
  • 在以上情况下,如果用户降低了分辨率
    • 居中点对点显示,显示完按钮宽度所用的屏幕像素个数为 96
    • 拉伸显示,显示完按钮宽度所用的屏幕像素个数大于为 96,虚拟的系统像素个数依然等于 96

接受现实

看看按钮实际的大小,你会发现,影响因素真的太多太多了!当我们不再沉浸在 DIP 的理想中,不再纠结有效像素的愿景的时候,便能觉得有效像素其实为我们考虑 DPI 缩放问题做了不少努力,确实能减轻我们 UI 的开发工作量。

本文会经常更新,请阅读原文: https://walterlv.com/post/introduce-uwp-effective-pixels-into-wpf.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://walterlv.com复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • [UWP]XAML中的响应式布局技术

    响应式布局的概念是一个页面适配多个终端及不同分辨率。在针对特定屏幕宽度优化应用 UI 时,我们将此称为创建响应式设计。WPF设计之初响应式设计的概念并不流行,那...

    dino.c
  • Grid 布局算法!自己动手实现一个 Grid

    2018-05-20 07:11

    walterlv
  • [UWP]使用Writeable​Bitmap创建HSV色轮

    HSV都是一种将RGB色彩模型中的点在圆柱坐标系中的表示法,这种表示法试图做到比RGB基于笛卡尔坐标系的几何结构更加直观。HSV即色相、饱和度、明度(英语:Hu...

    dino.c
  • dotnet 读 WPF 源代码笔记 WriteableBitmap 的渲染和更新是如何实现

    在 WPF 框架提供方便进行像素读写的 WriteableBitmap 类,本文来告诉大家在咱写下像素到 WriteableBitmap 渲染,底层的逻辑

    林德熙
  • 关于WinForms的跨显示器DPI自适应

    WinForms 是运行在Windows上的传统.NET桌面应用技术框架。由于历史原因,它对高DPI以及跨不同DPI屏幕的支持有些问题,本文将探索尽可能的解决方...

    Edi Wang
  • [UWP]UIElement.Clip虽然残废,但它还可以这样玩

    用了很久很久的WPF,但几乎没有主动用过它的Clip属性,我只记得它很灵活,可以裁剪出多种形状。在官方文档复习了一下,大致用法和效果如下:

    dino.c
  • WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件

    在 WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit) 一文中,我们...

    walterlv
  • WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)

    发布于 2018-07-12 07:57 更新于 2018-09...

    walterlv
  • 基于超像素导向的高光谱图像鉴别低秩表示(CS)

    在综合分析高光谱遥感影像局部空间信息和低秩特征的基础上,提出了一种新的高光谱遥感影像分类方案SP-DLRR。SP-DLRR主要由两个模块组成,即分类引导的超像素...

    用户8440711
  • WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)

    Windows Community Toolkit 再次更新到 5.0。以前可以在 WPF 中使用有限的 UWP 控件,而现在有了 Wind...

    walterlv
  • 使用像素相邻技术进行皮肤颜色分割的有效像素方法

    本文提出了一种新型的皮肤颜色分割技术,克服了现有技术(如颜色范围阈值)所面临的局限性。皮肤颜色分割受到不同的皮肤颜色和周围照明条件的影响,导致许多技术的皮肤分割...

    用户8436237
  • dotnet 从入门到放弃的 500 篇文章合集

    博客包括 C#、WPF、UWP、dotnet core 、git 和 VisualStudio 和一些算法,所有博客使用 docx 保存

    林德熙
  • 【译】Visual Studio 2019 中 WPF & UWP 的 XAML 开发工具新特性

    自Visual Studio 2019推出以来,我们为使用WPF或UWP桌面应用程序的XAML开发人员发布了许多新功能。在本周的 Visual Studio 2...

    郑子铭
  • WPF 使用 Composition API 做高性能渲染

    在 WPF 中很多小伙伴都会遇到渲染性能的问题,虽然 WPF 的渲染可以甩浏览器渲染几条街,但是还是支持不了游戏级的渲染。在 WPF 使用的 DX 只是优化等级...

    林德熙
  • [WPF自定义控件库]以Button为例谈谈如何模仿Aero2主题

    除了以外观为卖点的控件库,WPF的控件库都默认使用“素颜”的外观,然后再提供一些主题包。这样做的最大好处是可以和原生控件或其它控件库兼容,而且对于大部分人来说模...

    dino.c
  • Windows桌面程序开发

    最近在做Windows桌面程序开发,最初考虑到团队的技术构成(没有.NET开发),决定用Electron作为解决方案来开发,但是最后因为需要实现应用向其它未处于...

    剑行者
  • .NET 基金会项目介绍-MvvmCross

    MvvmCross 是属于 .Net 基金会的一个项目,本文将简要介绍该项目相关的信息。

    newbe36524
  • 如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案

    2017-10-21 03:20

    walterlv
  • UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)

    发布于 2018-04-15 09:37 更新于 2018-12...

    walterlv

扫码关注腾讯云开发者

领取腾讯云代金券