最近处理了一个关于DPI的问题,想想挺有意思的,拿出来分享一下。先搞清楚一下几个概念:
- DPI:dots per inch ,每英寸的点数。我们常说的鼠标DPI,是指鼠标移动一英寸的距离滑过的点数;打印DPI,每英寸的长度打印的点数;扫描DPI,每英寸扫描了多少个点。(更多请参考百度百科http://baike.baidu.com/view/49853.htm)
- 像素:pixel,picute和element的缩写。像素可以简单的理解为DPI里面的点。例如,显示器的分辨率为1024像素*768像素,就是说显示器的横向可显示1024个点(像素),纵向科研可以显示768个点(像素)。有的显示器每个显示点排列的比较紧密,1英寸的长度内可以排列的点就多一些,有的排列比较疏松,点就少一些,所以像素和英寸之间是没有直接的关系。(更多请参考百度百科http://baike.baidu.com/view/575.htm)
- 分辨率:如上例,但是我们常说调整一下显示器的分辨率,是啥意思呢?显示器有一个自然的分辨率,就是显示器的最大能耐,比如说,显示器的自然分辨率为1600*1200,那么长度小于1600、宽度小于1200的分辨率都可以显示的,1900*1300这样子的分辨率就不行。
- Set Custom Text Size(DPI):WIN7这个DPI我个人觉得,和上述的DPI不是一回事,不知道为啥微软把这个东东也叫DPI。首先,显示设备的物理DPI是不太可能改变的;其次,朋友们发现,这个DPI的默认值是96,也就是1英寸打印96个像素,当我们把DPI调整为125后,1英寸打印125个点。我们的大多数应用程序界面是按照96DPI设计的,到了125DPI后,1英寸的长度不再是1英寸,应该小一点,实际上,没有变小,反而变大了,所以,我觉得和上述的dpi不是一回事,最起码不是改变物理DPI。
然后仔细想想,类似于xp的放大镜功能,而且提示是“Make it easier to read what is on your screen”,所以,我觉得,应该是这么个意思,原来1英寸用96点来打印,您老人家觉得看不清楚,那我点之间的间距不变,用125个点来打印,这样子打印出来,大于1英寸了,您老估计能看清楚了。
好了,言归正传,WPF 是这样子处理的,他不管硬件是什么样的DPI,也不管操作系统是什么样的DPI,统统按照96DPI来计算,也就是说,WPF里面的一个像素就等于1/96英寸。于是,问题似乎就出来了,在设计的时候,我们都是在96DPI下面进行的,到了客户机器上后,千奇百怪的问题出现了,如下:
- 96DPI下,显示器分辨率为1024*768,应用程序的界面宽度为900,当到了125DPI的时候,傻眼了,界面被活生生的裁剪了一块,尤其是绝对定位的情况。咋办呢?给window设置MinHeight 和MinWidth ,让这两个值等于Height和Width。高DPI下,windows很过分,他发现他显示不了界面的所有宽度后,尽力而为了,能显示多少就弄多少,该裁剪的裁剪了,当设置了Minheight后,就相当于强制显示,必须至少显示这个尺寸,他就范了。
- 高DPI下,当前应用程序A与其他的应用程序B交互,B告诉A:在(600,500)的位置显示,也就是命令A.Left=600,A.Top=500 ,B的这个尺寸是按照高dpi(例如125)计算出来的,是已经被放大过的。A是wpf程序,只认识96DPI,所以,A不能老老实实的按照这个点显示,而是需要转换一下:A.Left=600/(125/96),WPF重绘后, windows再殷勤的放大一下,就吻合了B的要求。
- 高DPI下,wpf应用程序的宽和高的设定,类似于2中left和top的设定,需要做一下转换。如果说需求是宽高随着dpi自动放大,那就不用这样子处理了。
- 字体的问题,win7 里面DPI的方法,是为了字体更大一些,更容易看清楚来设计的。如果DPI很高,又要处理多国语言,有些语言翻译后很长很长,字体有大,尺寸有限,这个时候,可能需要酌情转换字体大小了。
以上纯属个人观点,如果不正之处,敬请指正。