• DPI适配之理论篇


    本文介绍在DPI适配中的一些原理性知识,为下一篇实践篇打下基础。文章主要内容来源MSDN以及相关博客,

    DPI是什么

    DPIdots 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被引入,在Win7Win8Win8.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有以下处理情况:

    1. 应用在高DPI下运作正常,并通知系统自身支持。应用清晰显示,行为正确。
    2. 应用在高DPI下运作正常,未通知系统自身支持。系统会缩放窗口,显示模糊但行为正确。
    3. 应用不支持高DPI,却错误通知系统自身支持:程序界面显示错位或者大小不正确。
    4. 应用不支持高DPI,未通知系统自身支持:系统会缩放窗口,窗口显示模糊,无错位。因为应用看到了"缩小"的屏幕分辨率。

    Win10缩放机制

    Win10的DPI缩放机制针对所有DPI缩放级别均采用DPI虚拟化机制,保证界面正常。针对DPI档位,固定为以下几种类别: 100%, 125%, 150%, 175%, 200%,225%,250%, 300%。

    确定应用程序支持DPI缩放级别

    下载并运行Sysinternals 进程浏览器,处理资源管理器,点击列,查看"DPI识别"列即可。

    参考文章:

  • 相关阅读:
    HDU 1540 Tunnel Warfare (线段树区间合并)
    P2258 子矩阵
    P5021 赛道修建
    P4084 [USACO17DEC]Barn Painting
    P3914 染色计数
    比赛用模板
    P3594 [POI2015]WIL-Wilcze doły
    P5022 旅行
    P3952 时间复杂度
    P3960 列队
  • 原文地址:https://www.cnblogs.com/cherishui/p/13209789.html
Copyright © 2020-2023  润新知