DPI适配之理论篇
本文介绍在DPI适配中的一些原理性知识,为下一篇实践篇打下基础。文章主要内容来源MSDN以及相关博客,
DPI是什么
DPI
是dots per inch
的英文简称,表示显示器固定区域内的像素密度,是逻辑单位。随着显示设备的进步,在高分辨率显示屏上显示的内容会越来越多,增大DPI选项,可更改屏幕上的文本大小以及其他项,优化显示效果。
DPI
缩放比例和屏幕分辨率是两个独立的属性,可独立设置。但它们之间有制约,在特定分辨率下,只允许缩放指定DPI比例,一般来说,更大的分辨率,支持更多的缩放级别。
默认DPI
缩放比例为100%(96),即10点大小的宋体文字分辨率是每英寸显示96像素点。如果比例改为125%,同样大小的字体,每英寸长度显示120像素(96*1.25=120),看起来显示变大了。
高DPI适用场景:
- 多显示器情况,每个显示器有不同的DPI缩放因子和分辨率
- 将高DPI显示设备在外接低DPI显示屏上,或者相反
屏幕分辨率
显示设备的分辨率定义了屏幕上显示的像素数量,比如,27寸显示器的分辨率是2560*1440px,表示它的宽有2560个像素,高有1440像素。针对物理显示尺寸,有最佳分辨率,分辨率可以调整,同样分辨率的显示,它能跟墙一般大,也可以跟手掌一样小。
在相同DPI下,如果减少分辨率,那每个像素点占据的空间会变大,操作系统会自动拉伸像素来填充。
传统缩放机制
传统缩放机制被Windows XP所采用,操作系统会按照设置DPI对应用进行缩放,由开发者自行检查缩放后是否存在问题。
- 优点字体清晰
- 处理不好会出现排版错乱,文本框重叠,文字溢出,界面越界等
现代缩放机制
现代缩放机制又称为DPI虚拟化,进一步细化不同缩放比例的处理,不让老程序在高DPI下出现界面错位。
- DPI缩放比例不超过125%,使用传统DPI缩放机制
- 超过125%缩放比例
- 程序报告支持自适应DPI:系统停用DPI缩放,缩放交由程序自身管理。
- 未报告自适应DPI,即非DPI-Aware程序:
- 整数倍缩放,如200%,300%,将原有界面中的1点扩展为4点/9点
- 非整数倍缩放,如150%,175%等, 系统会先向应用提交缩放前的分辨率,由系统按照该比例进行渲染,然后通过图像插值放大到指定DPI级别。
例如:原始分辨率为19201080,按150%比例缩放,那呈现给应用的是1280720分辨率进行渲染,应用看到的分辨率降低了,具体计算方式如下:1920/150% = 1280, 1080/150% = 720,再用常规图像插值算法进行放大,插值算法会导致界面模糊,显示锯齿等问题。
该机制从Vista被引入,在Win7
、Win8
、Win8.1
上都有采用。
默认情况下,WIndows认为应用程序是DPI-unAware,应用程序通知系统支持高DPI有以下三种方式:
- 方式一:在主进程的manifest中写入信息,如下配置:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<dpiAware>true</dpiAware>
</windowsSettings>
</application>
</assembly>
具体参考链接:Setting the default DPI awareness for a process
- 方式二:使用SetProcessDpiAwareness函数,设定DPI支持程度
- Process_DPI_Unaware: 不支持高DPI,由系统来负责缩放
- Process_System_DPI_Aware: 支持主屏幕高DPI,不支持多屏幕下的不同DPI
- Process_Pre_Monitor_DPI_Aware:支持不同屏幕不同DPI缩放
注意,在Win8系统上有SetProcessDPIAware,该API在之后新版本被废弃。在Win8.1以及Win10上应该使用SetProcessDpiAwareness,
- 方式三:通过启动程序右键快捷方式中开启"在高DPI下禁用界面缩放"。设置该项,表明应用向系统通知自身支持高DPI,不建议这样来操作。
第三方应用程序针对DPI有以下处理情况:
- 应用在高DPI下运作正常,并通知系统自身支持。应用清晰显示,行为正确。
- 应用在高DPI下运作正常,未通知系统自身支持。系统会缩放窗口,显示模糊但行为正确。
- 应用不支持高DPI,却错误通知系统自身支持:程序界面显示错位或者大小不正确。
- 应用不支持高DPI,未通知系统自身支持:系统会缩放窗口,窗口显示模糊,无错位。因为应用看到了"缩小"的屏幕分辨率。
Win10缩放机制
Win10的DPI缩放机制针对所有DPI缩放级别均采用DPI虚拟化机制,保证界面正常。针对DPI档位,固定为以下几种类别: 100%, 125%, 150%, 175%, 200%,225%,250%, 300%。
确定应用程序支持DPI缩放级别
下载并运行Sysinternals 进程浏览器,处理资源管理器,点击列,查看"DPI识别"列即可。
参考文章: