分辨率与DPI组合

昨天看到园子里的一篇关于DPI的博客,我没看太懂。相信有很多人对分辨率和DPI不是很清楚。网上也没有好的解释。我补个漏。

假设有这么回事:诺基亚和微软合作以后,出了一款搭载Windows 7的平板电脑: nPad,屏幕大小10英寸×8英寸,物理分辨率是960×768.也就是说每英寸有96个物理像素点(显像点)。

你为nPad编写了一个Windows版本的《愤怒的小鸟》,小鸟宽度为屏幕1/10(也就是1英寸)时最合适。在Windows中屏幕分辨率有两种960×768,480×354,为了充分利用屏幕的物理特性,也为了讨论简单,在Windows中设置为960×768,这样一个物理像素就等于一个物理像素点(显像点)。Windows的DPI缺省设置成96

假设WPF的单位是物理像素,那么你在程序里写下:bird.Width = 96,这时宽度正好是屏幕的1/10,也就是1英寸。注意此时和DPI的设置没有关系,因为使用的是物理像素。到现在为止一切都很好。

过了一段时间诺基亚推出了nPad2,屏幕当然还是10英寸×8英寸,但是物理分辨率是1920×1536,也就是每英寸有192物理像素点(显像点)。分辨率提升了,显示更细腻更逼真了。而你把Windows分辨率设置成了1920×1536(再一次:为了充分利用硬件,也为了简单:一个物理像素就等于一个物理像素点)Windows的DPI依然缺省设置成96。

此时问题出现了,你的程序是bird.Width=96,是以物理像素为单位的。那么96个物理像素变成了屏幕的1/20,也就是0.5英寸的,你的小鸟变小了,看着费劲了!那怎么办?应该把小鸟的宽度设置成192个像素,程序改为:bird.Width=192,此时又成了1英寸了。这等于我们要根据不同的屏幕,写不同的程序。还有一种方法我们不讨论了,就是把Windows分辨率设置成960×768(注意:此时1个物理像素就等于4个物理像素了),这样一来硬件白升级了。

问题出在哪里呢?是因为屏幕的物理分辨率是变化的,我们的WPF程序不应该以物理像素为单位,而应该用逻辑像素为单位,这个逻辑像素是多大呢?WPF规定为DPI/96。这样一来,我们的程序就不用改了,只要我们告诉Windows,DPI是多少就行了,OK,我们在Windows中设置了DPI为192(nPad2的屏幕确实1英寸有192个物理像素点,这是符合事实的).此时小鸟又是1英寸宽了。

也就是让Windows知道这个设备的每英寸有多少个物理像素点。这样Windows就会把bird.Width = 96 语句换算成真正的192个像素(96*(192/96),这里的192就是DPI的值)。问题得到了圆满解决。

简单地说,就是屏幕物理分辨率提升了(不是分辨率增大,如果一个20英寸宽的屏幕,物理分辨率为1920×1536,这块屏幕精确程度,细腻程度和nPad没有区别),DPI也随之变化,以抵消屏幕分辨率变化对程序产生的影响,这里的物理分辨率可以叫做“设备真实DPI”

WPF程序中设置了小鸟宽度为96,并不是说这个小鸟就是1英寸,需要把显示器的分辨率和DPI都设置匹配了才是1英寸。

在WPF中1个逻辑像素,当DPI是96时,等于1个物理像素。当DPI是192时,等于2个物理像素......再也不硬性制定长度单位是1个物理像素了。

posted @ 2011-03-03 13:33  吾爱孟夫子  阅读(3358)  评论(1编辑  收藏  举报