天天看點

dpi詳解

一、必須掌握的概念 DPI (以下讨論先避免 sub-pixle 子像素渲染技術,以免混淆)

看過無數流行的漢化或字型美化的文章,往往存在一個緻命傷,即忽略了 DPI 這個重要概念,是以是不完整的。

DPI 原來是印刷上的記量機關,意思是每個英寸上,所能印刷的網點數(Dot Per Inch)。但随着數字輸入,輸出裝置快速發展,大多數的人也将數字影像的解析度用DPI表示,但較為嚴謹的人可能注意到,印刷時計算的網點(Dot)和 電腦顯示器的顯示像素(Pixel)并非相同,是以較專業的人士,會用PPI(Pixel Per Inch)表示數字影像的解析度,以區分二者。而在本文中我們約定兩個概念可以互換,即 DPI 就是 PPI。

參考: Coming to Terms with DPI, PPI and Size

問題一: dpi 和我們的 LCD 屏有什麼關系呢?

把眼睛湊近螢幕,容易發現我們的螢幕是由一個個小方格組成,我們稱這些方格為像素,LCD 中有個術語叫螢幕的 native resolution(實體解析度),指的的就是螢幕所包含的像素數量,比如我的 TFT LCD 14" native resolution 為 1024x768,即水準由 1024 個像素組成,垂直由 768 個像素組成。通常讓我們的 LCD 工作在 native resolution,成像效果最好。

通過控制像素的開關和色彩的組合來顯示我們需要的圖像,但不要忽略了螢幕像素的數量是有限的,是以往往在低解析度的顯示裝置上看到的圖像并不十厘清晰,比 如在觀察白底黑字(或黑底白字)的文字時,文字的邊緣有尖銳的鋸齒狀(階梯狀),長時間觀看,眼睛很容易疲乏,這也就是很多人喜歡看紙制書籍的一個重要原 因,制作精良的紙張,它包含的“像素”可以達到很高,邊緣看起來非常的流暢。

問題二: 有什麼辦法可以解決或緩解上述缺陷呢?

除了通過各種輔助技術(hinting,anti-alias,sub-pixel,etc.)改善成像效果外,最快捷的途徑是換一台高解析度(高分屏或高 dpi) 的螢幕,簡單說像素越精細越好。

講到這裡你可能很關心自己的螢幕的 dpi 具體為多少?(拿去和别人炫耀 :)

到這裡找找看有沒有你的 LCD dpi 資訊: http://www.prismo.ch/comparisons/notebook.php

問題三: 如果找不到,如何來手工計算?

找把尺子,把 LCD 屏可視區域的寬和高量一下,比如我的螢幕 width = 287 mm = 28.7 cm,height = 215 mm = 21.5 cm

換算比例: 1 cm = 0.39 inch, 1 inch = 2.54 cm

水準 dpi = 水準 resolution * 2.54 / width = 1024 * 2.54 / 28.7 = 90.6 

垂直 dpi = 垂直 resolution * 2.54 / height = 768 * 2.54 / 21.5 = 90.7

故我的 dpi 大概為 90x90,在某些機子上水準 dpi 和 垂直 dpi 會不相當,這是很正常的。

問題四: 下面我們看看自己的單個像素具體有多大?

術語: pixel pitch - 像素間距,即單個像素的水準寬度,類似于 CRT 的 dot pitch(點距)

我的 TFT 14" 1024x768

pixel pitch = 28.7 / 1024 = 0.028 cm = 0.28 mm

而一台 T43 高分屏 SXGA+ 14" 1400x1050, pixel pitch = 0.2047 mm

可以看出 SXGA+ 14" 要精細的多。羨慕啊!

問題五: 我要顯示一個 px = 12 的文字,實際看起來會有多大?

術語: [color=red]px(pixel size) - 顯示單個文字需要的水準像素數量

實際大小 = px * pixel pitch 

TFT 14" 1024x768: 12 * 0.28 = 3.36 mm

SXGA+ 14" 1400x1050: 12 * 0.20 = 2.4 mm

看到這裡高分屏的使用者應該明白為什麼同樣是 12 px 的 SimSun 點陣字型(bitmap font),在自己的螢幕上看起來要小很多,因為你的 pixel pitch 小。pixel pitch 小不是更好麼?

不是不好,而是字太小了,看起來太累,為了保護你的視力,你應該選擇大一些的 px。

但要注意中文點陣字型提供商并沒有為每個 px 制作點陣漢字,因為中文點陣都是手工繪制的,需要很高的專業技能,非常耗時,故一般隻繪制最常用的 px,而且點陣的一個最大的缺點就是不能夠縮放,每個點陣漢字的每一個像素都是事先安排好的,縮放後打亂了原有的布局,比如出現破碎,高高低低之類的現 象,使字型變得非常醜陋。

好在 winxp 帶的 simsun.ttc 除了 outline 字型外,還包含了豐富的點陣,ppem(pixels per em)分别為 12px, 13px, 14px, 15px, 16px, 18px,你可以根據你的需要選擇。例如選擇 16px:

實際大小 = 16 * 0.20 = 3.2 mm,這樣看起來和 14" TFT 上的 12 px 字就差不多大小了。

當然因為 ppem 不同(或 px 不同),繪制點陣字型時的空間自由度也不同,出來的點陣效果也不同,而且豎線橫線比劃一般都隻占用一個像素寬度,在高分屏上 16px 看起來會有細胳膊細腿的感覺,這也就是為什麼不少人會覺得 12px 在 14" 1024x768 上會比較好看,比較符合東方人對中文的審美觀。

要注意,由于點陣字型以上的缺陷,通常用在低解析度的螢幕上,現在随着技術的發展,螢幕解析度逐漸提高,越來越流行使用 outline 字型,這種字型可以随意的縮放,而不影響形狀,現在高分屏使用者可以嘗試用黑體,如 mac os 帶的華文細黑或微軟新出的雅黑,黑體比劃很粗,适合一部分人的審美觀,在大螢幕上效果比較好。

問題六:既然 dpi 都不一樣,我要去和别人讨論字型大小,如何講清楚該字型究竟有多大呢?

真是一個難題,顯然用 pixel 這個相對度量去讨論是不合适的,誰也說不清。是以這裡我們引入另外一個重要機關 point(磅)。

1 point = 1/72 inch

這裡的 inch 就是實際生活中使用的 inch。沒錯 point 才是絕對度量,比如一個 9 point(9磅)的字的實際大小:

9 * 1/72 = 1/8 inch = 1/8 * 2.54 cm = 3.175 mm

這樣的話,大家才能從同一個标準出發讨論問題。是以你看到 MS office word 裡的 size,都是以 point 為機關的。

注意,不同家族的字型,如 Arial 和 Verdana 字型,由于設計思路不同,同樣磅值的字,看起來 Verdana 感覺要大一些。

Arial VS Verdana

不要讓 windows 蒙蔽了你的眼睛!

由于顯示器市場的混亂,不同産品 dpi 都不同,為了統一,windows 預設設定 dpi 為 96。注意這裡的 dpi 不是你機器的實際 dpi,而是 windows 給你強加上去的。

統一的 96 dpi 有它的優點,因為市面上大多數的顯示器 dpi 和這個值接近,而且大多數人都是用 wndows 來設計網頁,是以無形中 96dpi 成了一個 de facto 上的标準。但缺點也是很明顯的,設計師在 96 dpi 顯示器上設計的網頁到了 120 dpi 的機器上看起來可能效果會差強人意。是以現在有人建議設定 em 值,這個已經超出我的知識範圍。

問題七:你在自己機器上看到的 9 point 還是 9 point 大麼?

初看這句話好像自相沖突,難不成 1 != 1 了!國小老師欺騙了俺?!

别着急!因為你打開 MS word,字型設定欄裡看到的 9 point 字,很可能是錯誤的資訊。

假如你運氣很好,你的機器實際 dpi 剛好為 96 dpi,那麼恭喜你,你沒受騙,你看到的是正确資訊,如果你的實際 dpi 和 96 相差比較大,那麼你看到的是虛假資訊。為什麼這麼講呢?

我們來做幾道國小數學題:

文字在 LCD 上成像,不管是 bitmap font 還是 outline 字型,最終都是以像素繪制。

比方我有一台實際 96 dpi 的 LCD,我要顯示一個 9 point 大小的字,我們來看看具體需要多少像素 px?

換算公式: px = pt * dpi / 72

96 dpi, 9 pt: px = 9 * 96 / 72 = 12

作業系統水準要用 12 個像素來描繪該字。

螢幕上看起來有多大?

12 * pixel pitch 

假如我通過各種手段人為的把 dpi 改成了 72,來算一下需要的像素值 px?

72 dpi, 9 pt: px = 9 * 72 / 72 = 9

螢幕大小:9 * pixel pitch

注意 pixel pitch 是不變的,計算方法見上文。

現在作業系統就以 9 個像素給你描繪該字,顯然比 12 像素描繪出來的小。

這也就是為什麼很多人抱怨 Debian/Ubuntu 下預設的 75 dpi ,設定為 9 ponit 的字會看起來比 windows 96 dpi 下小的多的緣故。

此時最可能發生的做法就是,把 9 point 改成更高的 point,而不知其實是 dpi 在跟你開玩笑呢!正确做法,應該先調整好系統 dpi,使之接近你的實際 dpi。

再結合高分屏來讨論一下。

問題八: 同樣顯示一個 9 point 字(即實際大小一樣),顯然在 TFT 上需要描繪該字的像素比較少,因為像素個頭比較大,而在 SXGA+ 上用來描繪的像素多,個頭細,哪個會看起來更漂亮些呢?

我猜你會毫不猶豫選擇後者,好比用一個高 dpi 的數位相機拍攝同一個場景,拍出來的效果比低 dpi 要好的多。

但我隻能部分同意,還要看你選擇的是哪種字型。

如果你正在使用 outline 字型,它是可以任意縮放的,明顯同樣大小在 SXGA+ 上的表現要好很多,即字型邊緣更加光滑流暢,好比在一張好的和畫布上作畫。

點陣字型要分情況讨論,不要忘了點陣字型是不能縮放的,而且 px 并不完整,隻繪制了一些最常用的 px。

例如:

拿兩台實際 dpi 分别為 96 和 72 的機器來讨論,同樣顯示 9 point 的點陣漢字。

上面已經計算過,dpi 96 要用 12 px, dpi 72 要用 9 px 繪制該字。

而使用的字型隻帶了 9px, 10px, 11px, 13px,14px,15px .....,恰好沒提供 12px。

此時 96 dpi 機器上的 9 point 漢字,将會非常醜陋,因為此時的 12px 點陣是機器為你合成的,現在的 AI 還沒那麼智能,遠沒達到和人類一樣的審美能力。就好比一台高性能手機,可惜不在伺服器,任你本事多強,也無用武之地,多郁悶啊!

而 72 dpi 的機器,9 point 剛好落在 9px,此時的字型比劃端端正正,自然效果會好的多。

以上的讨論也正說明了點陣字型的缺點,很不靈活。

是以在後面的讨論中,對于 outline 字型,我們用 point size 讨論, 直覺友善。而對于 simsun 内嵌的點陣(bitmap font)會用 pixel size 來控制比較好,因為用 point size 的話,還要進行換算,看看是否剛好落在特定的 px,而換算要用到 dpi,個人的實際 dpi 又不盡相同,事先沒法得知,故用 point size 是不合适的。

總結一下,dpi 在這裡就像是一個橋梁,将 point size 轉化為需要的 pixel size。

聽了這麼多,你也累了,休息一下吧!然後我們一起來實踐一下,注意 Linux 将會有多個需要調整 dpi 的地方,希望你能區厘清楚。

1、告訴 X server 你的實際 dpi

Debian/Ubuntu 下 X server 預設會使用 75 dpi,可以通過以下指令檢視你的 X server 的 dpi 設定:

代碼:

$ xdpyinfo |grep resolution
resolution:    75x75 dots per inch
        

因為我的實際 dpi 為 90, 故 75 對我來說低了。如果讓 X server 工作在正确的 dpi,有多種途徑,而且不同發行版略有差異,由于篇幅所限,隻能部分介紹,具體請參考:

Mozilla DPI-related Font Size Issues on Unix

Solving the Linux DPI Puzzle

引用其中的幾句話,簡單看一下有哪幾種和它們的優先級:

引用:

How the XFree86 and Xorg servers calculate DPI

The DPI of the X server is determined in the following manner:

1. The -dpi command line option has highest priority.

2. If this is not used, the DisplaySize setting in the X config file is used to derive the DPI, given the screen resolution.

3. If no DisplaySize is given, the monitor size values from DDC are used to derive the DPI, given the screen resolution.

4. If DDC does not specify a size, 75 DPI is used by default. 

You can check what DPI your X server is set to by running xdpyinfo | grep resolution in a terminal window.

對于 Debian/Ubuntu 我采用方法 2,下面的設定改成你自己的,注意 dpi 的數值最好為 6 或 12 的倍數,原因:

引用:

As above, if this works, but at less than 100% satisfaction, tweak the number lower or higher to suit your preference. If possible, use a number that is a multiple of 6, or even 12, as numbers that aren't sometimes result in annoying rounding errors that cause adjacent bitmap font sizes to not increment and decrement linearly.

同時你可以更加自己的滿意程度,進行微調。

代碼:

$ vi /etc/X11/xorg.conf 加入
Section "Monitor"
	  ......
          DisplaySize   287     215     # 1024x768  90dpi
	  ......
EndSection
        

這裡的 287, 215 即我的實際顯示區域的寬和高,機關為 mm。

重新開機 X 後,生效。以 gdm 為例:

代碼:

$ /etc/init.d/gdm restart
        

檢視是否生效:

代碼:

$ xdpyinfo |grep dimensions
  dimensions:    1024x768 pixels (289x217 millimeters)
$ xdpyinfo |grep resolution
  resolution:    90x90 dots per inch
        

告訴 X server 實際 dpi 後,最直覺的感覺就是用 gdm 登入管理器,在使用預設 75dpi 下,gdm Option 菜單和輸入框中的字型會顯得較小,其它的變化待大家慢慢發覺吧!

2、fontconfig/xft

對于傳統的程式或系統,使用 legacy x font server,簡稱 xfs,那麼上面的做法應該已經足夠,但對于現在的程式來說,通常使用 fontconfig/xft,還得做進一步的工作。

引用:

Unfortunately, variations in the implementations of X mean display size reconciliation as above won't be a solution on every system. Failure here seems to be common on newer systems using fontconfig instead of legacy xfs

代碼:

$ vi /etc/fonts/local.conf 或 vi ~/.fonts.conf 加入
<!--
   Target dots per inch
 -->
        <match target="pattern">
                <edit name="dpi" mode="assign" >
                        <double>90</double>
                </edit>
        </match>
        

fontconfig 将根據該 dpi 值來進行字型的 point size 到 pixel size 的轉換,具體過程參考:

fontconfig 中 pixel size 的計算過程

據我實踐,kde Qt3 程式會使用該值,包括 kdm,用該值來控制 Qt3 程式的字型 dpi 比較友善。

3、dpi in gonome

引用:

GNOME also offers an interface to set the Xft DPI. If "gnome-settings-daemon" is running, this will advertise the DPI value set in the gnome-font-properties dialog to GNOME applications via XSETTINGS, and set the Xft.dpi X resource. Any Qt application started after gnome-settings-daemon is running will use the Xft.dpi value configured by GNOME.

簡單說 gnome 額外提供了一個接口來更加靈活的控制設定 fontconfig/xft 程式的 dpi,當你運作 gnome 時,将會運作 gnome-settings-daemon 這個守護程序,來通知 Gtk2 程式 dpi 值,同時設定 Xft.dpi 來影響 Qt 程式。 

操作方法,在 gnome 的字型功能面闆 dpi 設定欄裡輸入 90,就可以了,你可以根據喜好,進行微調,馬上能見到效果。

檢視 Xft.dpi 值,方法如下:

代碼:

$ xrdb -query
......
Xft.antialias:  1
Xft.dpi:        90.00000
Xft.hinting:    1
Xft.hintstyle:  hintfull
Xft.rgba:       rgb
        

據我實踐,Gtk2 程式标題欄和菜單欄字型發生明顯變化,包括 gnome 的開始菜單、工具欄、桌面字型等等,。而對于 Qt3 程式,除了标題欄發生變化,其它穩絲不動,是以還是得通過 fontconfig 修改。

細節:

如果 gnome 中的 dpi 和 X server 中的不同,而且相差很大,比如一個 120,一個 90。那麼你在登入到 gnome 那一瞬間,會發現開始菜單的字型一下子變大,原因是最開始時 gnome-settings-daemon 還沒運作。

4、字型大小不等,dpi 惹得禍

如果你在使用 kde 或 fvwm 之類,而又沒有運作 gnome-font-properties,那麼你會發現同樣是 9 point 字,gtk2 程式和 Qt3 程式的顯示大小不同。例如你打開 gnome terminal 和 kde terminal 比較一下。

解決方法:

$ vi ~/.Xresources

代碼:

Xft.dpi: 90
        

我的了解是 kde 會自動讀取 fontconfig 的 dpi 的設定,而 gtk2 程式依賴 Xft.dpi。