五、解析度與橫豎屏
我花費了巨多的時間來處理DPI和解析度的問題,說出來可能大家都不信,1/3到1/4的總開發時間,都是在處理DPI和解析度相關的問題,這實在令人費解,因為當今的Android和IOS開發幾乎不用考慮這些問題,Windows Phone 7和Windows8也不用,我怎麼如此折騰?
5.1,花點篇幅講講“解析度”
解析度(Resolution)在不同時候指的可能是不同的東西,有時候指的是螢幕像素,有的時候指的是點的密度。如“1024*768”,這指的是水平像素和垂直像素,而“96DPI”,則是點的密度(Dots Per Inch),DPI越高,點的密度越大。那麼Windows的DPI設定是什麼意思?
(Windows控制台中的DPI設定,通過“控制台 - 外觀和個人化 - 顯示 - 設定自訂文字大小(DPI)”開啟)
預設情況下,Windows認為顯示器的DPI是96,一個9號的宋體字,按照這個DPI去渲染,結果是這樣(放大10倍):
這個“宋”字使用了11*12個點繪製而成,在一個普通顯示器下顯示這個字應該是OK的,但試想現在新出了一款顯示器DPI特別高,點的密度特大,點間距特小,如果這個“宋”字還是使用11*12個點繪製出來的話,那就顯得太小了,眼睛看起來費勁,所以Windows提供了這麼一個調整DPI的選項,允許你放大Windows介面的元素,例如:如果你把DPI調整到192,那麼,這個“宋”字將會這樣顯示(放大10倍):
它變成了使用28*29個點去繪製,奇怪了,為什麼不是22*24?這是因為我把margin去掉了,理論上確實應該是長寬各兩倍的關係,相信大家明白。BTW:當你把自己電腦的DPI調整到192之後,你發現不光是字型變了,捲軸,菜單等很多Windows元素都變了,但有些又沒變,有些則顯示很怪異,這是為什嗎?因為並非所有的軟體都考慮到了DPI,許多軟體都只是按照預設的DPI去設計,所以我認為目前讓Windows使用更高的DPI的顯示器是沒有必要的,因為軟體層面的支援不足啊!那麼為什麼最新的視網膜屏的Macbook Pro沒這個問題?——那是因為Apple的工程師和設計師在其背後做了許多工作量大得你根本無法想象的的工作,但即便如此,還是有些軟體對視網膜屏支援不好,用多了你就會發現了。
所以,DPI這個選項的意圖是:使得在不同的DPI的顯示器中,同樣邏輯尺寸的一個介面元素顯示出來的物理尺寸一致。準確說基本一致,舉個簡單的例子:17寸標屏的液晶顯示器(現在絕版了)的標準解析度是1280*1024,而19寸的標屏液晶(也絕版了)顯示器也是這個解析度,那你認為誰的DPI更高?對Windows來說一樣,預設都認為是96DPI,而物理DPI的話當然是17寸的高一點,所以顯示同樣邏輯尺寸的介面元素時,17寸的顯示器看到的要小一點,(貌似我在講廢話)要處理這點細微的差距實在太繁瑣了,所以就近似吧,都把他們認為是96DPI即可。
最後再提一下PPI(Pixels Per Inch),其實跟DPI是一回事,只不過DPI用在印表機領域上較多,而Windows一直“DPI,DPI”地叫,我也跟著DPI了,大家知道印表機的DPI是多少嗎?現在主流印表機基本都支援2880 DPI的列印模式,其點的密度比顯示器大太多太多了……
5.2,Windows Mobile的DPI
Windows Mobile有3種DPI(其實可能還不止,但我這裡說我遇到過的),分別是:96、128和192,和像素解析度通常有以下關係:
螢幕解析度 |
DPI |
240*320 |
96 |
480*640 |
192 |
240*240 |
96 |
480*480 |
192 |
480*800 |
192 |
320*320 |
128 |
這是參考表,並非絕對,事實上,Windows Mobile的DPI是可以在ROM定製的時候配置的。
同樣一張貼圖,在96DPI的機器上正常,在192DPI的機器上就太小了;反過來,在192DPI機器上正常,在96DPI機器上就太小了——這就是我要解決的問題。
大家說怎麼辦?
一個解決方案是展開/壓縮圖片,但壞處有三個:
- 走樣。圖片的展開/壓縮會帶來走樣,實際使用起來是很影響美觀的。
- 資源浪費。如果96DPI的機器使用了為192DPI機器準備的貼圖的話,那是極大的浪費,很可能帶來資源枯竭的問題。(這個後面會提到)
- 效率低下。展開/壓縮比常規直接貼圖要耗費更多的CPU,可能帶來使用者介面響應的遲緩和更高的電耗。
我選擇了最繁瑣的解決方案:為不同的解析度準備不同的3套圖!
(不同DPI所使用的不同的貼圖)
如果你是專業美工,也許你能看出來,192DPI這個圖最完美,而96DPI和128DPI這兩個貌似有些毛糙,原因嘛,悄悄告訴你:由於我需要三套圖這個苛刻的要求,公司的美工對我意見很大……所以預設皮膚裡很多圖都是我自己直接用Photoshop的調整大小調出來的,從這反應出了我技術以外的相當不足的一面……
5.3,橫屏與豎屏
做電腦的軟體很少需要考慮橫豎屏的問題,但手機就得考慮了,在開發SoSoPi的過程中,我曾經接觸過一個山寨機,只有橫屏的,沒辦法把它調整為豎屏的,這種奇葩Android估計也不會有吧,可Windows Mobile是“一切皆有可能啊”。橫豎屏問題對於軟體來說是一個解析度調整的自適應問題,或者叫“重新布局”吧。480*800的解析度變味了800*480,介面上的元素得重新調整吧,這可真不是一件容易的事情。大家看看SoSoPi的首頁自適應方法:
(首頁的橫豎屏自適應)
從上看得出來,你至少需要面對的問題是背景圖的“自適應”,如果你是使用了480*800的背景圖,那在豎屏的時候是沒問題的,但到了橫屏,恐怕只能顯示480*480的大小,右邊的一大塊地區它填充不到,解決方案我想過很多,包括展開圖片,旋轉圖片等,但效果都不理想,最後的決定是:使用800*800的圖片,這樣無論橫屏豎屏都能填充滿了,而對美工來說稍微增加了一點難度,他得測試一張背景圖片在橫屏和豎屏下的不同的效果,使用者如果需要更改圖片的話,對圖片的選擇也有一定要求:如果螢幕長邊的長度為N,那麼就最好選擇N*N的圖片,比如480*640的螢幕,就選擇640*640的圖片為佳。
背景圖僅僅是其中一方面,我還得考慮很多很多的東西,介面元素是完全重新布局!這意味著我要做兩套布局來適應不同的螢幕狀態,可能表面上看看不覺得太難,但做起來發覺工作量還真大,介面上的許多元素不能直接指定座標了,而是得按照百分比來計算座標,在整個介面的繪製代碼裡,通篇都充滿著“橫屏”和“豎屏”的判斷。而介面元素的對齊,有些是從頂部開始,有些是從底部開始,有些是對別的元素取相對座標,有些則是取AB兩個元素之間的靠近A元素的30%的位置……
(這是日曆的橫豎屏對比圖)
除了麻煩之外,這裡面還有一個大問題。如果你看過前一篇關於貼圖的文章,你會想起圖片的緩衝,我為了加快貼圖速度,使用了一些空間換時間的演算法,也就是緩衝,現在回想一下,由於橫豎屏的切換,我的一些緩衝是不是也要跟著更新?——是的。比如之前我作了一個480*800的圖片緩衝區,現在變成橫屏後我得調整為800*480的,怎麼調整?把之前的刪了,重新建立。需要特別說明一下的是,這個動作很容易導致系統崩潰,因為Windows Mobile的資源十分有限,記憶體管理能力也遠不及Windows,重建圖片緩衝就是一個很耗資源的動作。對這個問題,直到最後我都沒有什麼好的解決方案。
5.4,現在還有這些問題嗎?
無限今日並不存在這些問題,因為無限今日的皮膚總是針對某個解析度(DPI及像素點)去設計的,使用者會根據自己的手機的實際情況去選擇不同的皮膚(橫豎屏的問題依然存在)。而現在的iPhone的APP開發,存在這些問題嗎?大體上也不存在,因為iOS的繪製使用的是裝置無關的單位,其實現在的幾乎所有的UI開發(包括微軟體系)都是偏向於使用裝置無關單位了,比如“厘米”和“英寸”這些單位,這樣就能確保在不同DPI的顯示裝置上顯示出來的物理尺寸基本一致,即便使用點,也是裝置無關的點,而不是直接對應到螢幕上的像素去,所以我們還可以使用浮點數來表示點的大小,比如線條的粗細為0.7個點,繪製出來的0.7個點粗細的線條給你感覺確實比一個點粗細的線還“細”,因為底層圖形庫在必要的時候會把它渲染的顏色改得更淺一些,總之你不需要再操心它具體用什麼顏色繪製了幾個像素了;橫豎屏切換呢?基本上不用考慮,僅僅在你的App需要特別地用到橫屏或豎屏的時候才需要考慮,比如查看一張橫向的照片的時候允許使用者把手機橫過來看,而其它大多數時候,你可以把你的設計固定為橫屏或豎屏。
最後留個問題在這裡,各位看看iPhone的“案頭”,你來弄個橫屏怎麼弄?(實際上不越獄的話,iPhone不允許案頭橫屏,但我假設可以,嗯,考考你們的設計能力)