WPF單位真的與分辨率無關嗎?

WPF從發佈之日起,一直將“分辨率無關(resolution independence)”作爲其亮點,聲稱使用WPF製作的用戶界面在輕巧的Ultra-Mobile PC的屏幕上和在50英寸的電視機上都能很好地顯示。微軟之所以稱WPF具備“分辨率無關”這一特性,主要是因爲WPF的座標單位設計成爲以1/96英寸爲一個邏輯像素單位,而不是與設備相關的像素單位。

  但是微軟本身對WPF“分辨率無關”這一特性沒有作更多的具體解釋,導致用戶會產生很多誤解。

  誤解之一

  改變顯示器的分辨率設置,同一個WPF的用戶界面和繪製的圖形尺寸不會變化。

  這個可以用一個非常簡單的實驗證明該結論是錯誤的。新建一個WPF應用程序窗口,其中高度爲400DIUs(DIU:Device independent unit,設備無關單位),寬度爲600DIUs,讓這個窗口分別在分辨率設置爲1280 * 1024和800*600的環境下運行,如下圖所示,兩個窗口的尺寸是明顯不一樣的。

WPF單位真的與分辨率無關嗎? WPF單位真的與分辨率無關嗎? 

  圖 1 左圖爲1280 * 1024分辨率,右圖爲800*600分辨率

  誤解之二

  改變顯示的DPI設置,同一個WPF的用戶界面和繪製的圖形尺寸不會變化。

  顯示的DPI設置,在XP系統下是通過右鍵——屬性——設置選項卡——高級,可以調用出來,如下圖所示:

WPF單位真的與分辨率無關嗎?

  圖 2 顯示屬性DPI設置

  這個也可以用同樣的方法進行證明該結論是錯誤的。仍然是高度爲400DIUs[1],寬度爲600DIUs的窗口分別運行在96DPI和192DPI兩種設置環境下。從下圖也可以明顯看出窗口的尺寸是不一樣的。

WPF單位真的與分辨率無關嗎?     WPF單位真的與分辨率無關嗎?    

  圖 3 左圖爲96DPI,右圖爲192DPI

  誤解之三

  在不同屏幕上,如果DPI設置相同,則同一個WPF的用戶界面和繪製的圖形尺寸不會變化。

  在這個地方有必要對屏幕的DPI設置進行一下解釋說明。DPI設置是指屏幕上每英寸多少個像素,比如當前設置爲96DPI,即屏幕上96個像素爲1英寸。一般的Windows XP系統有正常尺寸(96DPI)、大尺寸(120DPI)和自定義尺寸三種選項。既然WPF的座標單位是以1/96英寸爲一個邏輯像素單位,那麼我們有理由相信,如果兩個顯示器的DPI設置是相同的,那麼同一個WPF的用戶界面和繪製的圖形尺寸不會變化。很遺憾,這樣的結論依舊是一個錯誤。

  CalvinP.Schrotenboer 也用一個實驗證明這是一個錯誤。實驗環境如表 1,比如桌面LCD顯示器實際屏幕寬度和高度(像素單位)爲1600 x 1200,這個和普通的分辨率設置需要區分,這是顯示設備的最大分辨率或者說是物理分辨率,即物理上該顯示器屏幕上是1600 x 1200個像元,英文中又稱這種分辨率爲“native resolution(原生分辨率)”。由於兩個屏幕物理尺寸也不一樣,所以實際的物理DPI可以通過表中的計算公式得到。實際的物理DPI和操作系統的DPI設置是沒有什麼聯繫的。

  表 1實驗環境

 

  實驗環境

 

 

  系統一

 

 

  系統二

 

 

  顯示器類型

 

 

  桌面LCD顯示器

 

 

  筆記本LCD顯示器

 

 

  屏幕寬度和高度

  (像素單位)

 

 

  1600 x 1200

 

 

  1400 x 1050

 

 

  屏幕寬度和高度

  (英寸單位)

 

 

  17.0 x 12.75

 

 

  12.0 x 9.0

 

 

  實際的物理DPI

 

 

  縱向:1600 / 17.0 = 94DPI

  橫向:1200 / 12.75 = 94DPI

 

 

  縱向:1400 / 12 = 117DPI

  橫向:1050 / 9 = 117DPI

 

 

  操作系統的DPI設置

 

 

  96DPI

 

 

  96DPI

 

  在兩個不同系統當中運行同一個WPF應用程序,該程序了繪製了一條長爲384DIUs的直線,換算成英寸即爲384/96= 4英寸。結果在兩個系統當中的實際尺寸如下圖所示:

WPF單位真的與分辨率無關嗎?

  圖 4 上圖實際尺寸爲4.08英寸,下圖實際尺寸爲3.28英寸(CalvinP.Schrotenboer,2006)

  問題出在哪兒了?

  其實從表 1當中就能看出一些端倪,原因正是在於實際的物理DPI和操作系統設置的DPI不一致造成的。WPF無法知道當前使用設備實際的物理DPI爲多少,相反通過操作系統的API函數獲得操作系統的DPI值,然後簡單地認爲這就是實際的物理DPI值。比如在桌面LCD顯示器上,實際一個物理像元的尺寸爲1/94英寸,由於操作系統設置爲96DPI,因此WPF還固執地以爲一個實際的像元爲1/96英寸,因此線段長度爲1/94 * 384 = 4.08英寸。筆記本顯示器實際一個物理像元的尺寸爲1/117英寸,因此線段長度爲1/117 * 384 = 3.28英寸。這個值和我們測量的結果正好相符。

  那麼我們有理由推測,如果將操作系統的DPI設置成實際的物理DPI,則能做到真正的“分辨率獨立”,即在兩個不同顯示器上顯示的線段長度都爲4英寸,如圖 5所示:

WPF單位真的與分辨率無關嗎? WPF單位真的與分辨率無關嗎? 

  圖 5 左圖爲桌面LCD顯示器,將DPI設置成爲94,右圖爲筆記本顯示器,將DPI設置成爲117

  WPF的“分辨率無關”到現在爲止已經是山高月小,水落石出。那麼我們還要接着討論另一個問題,在顯示器上存在這樣的問題,那麼是否在打印機上也存在這樣的問題呢?仍然可以用一個實驗證明。同樣繪製一個4英寸的直線,分別在DPI設置爲96DPI和120DPI下進行打印,得到的打印結果尺寸相同。如下圖所示:

WPF單位真的與分辨率無關嗎?  WPF單位真的與分辨率無關嗎? 

  圖 6 左圖爲系統設置120DPI下打印結果,右圖爲系統設置96DPI下打印結果

  結論

  通過上面幾個實驗分析,我們可以得到如下兩個結論:

  (1)              WPF在打印得時候可以做到“分辨率無關”,即同一個WPF用戶界面和繪製的圖形尺寸在任何一臺打印機上輸出都是一致的;

  (2)              當顯示器實際象元的物理尺寸和系統設置的DPI保持一致的時候,WPF可以在顯示器上做到“分辨率無關”,即同一個WPF用戶界面和繪製的圖形尺寸在任何一臺顯示器(實際象元的物理尺寸和系統設置的DPI保持一致)上輸出都是一致的。反之則無法保證。

  更多的討論

  “分辨率無關”這樣一個概念,由於微軟本身討論得不多,的確容易造成誤解。最爲詳細地討論了WPF當中“分辨率無關”的是CalvinP.Schrotenboer 的一篇博文“Is WPF Really Resolution Independent?”。當然Charles Peztold也在自己的博客當中討論過這個問題。另外在微軟的論壇上StephenW,Charles Peztold等人也就WPF的“分辨率無關”和“設備無關”作了比較深入的討論。

發佈了45 篇原創文章 · 獲贊 6 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章