反鋸齒指南

Paul Lewis

引言

消除鋸齒是網路圖像中無常式的一面,因此我們螢幕上會顯示清晰的文字和平滑的向量形狀。目前,瀏覽器中使用的兩種反鋸齒方法,對於轉譯文字最為明顯。使用反轉交換機制的演算法可能會產生非預期的影像結果。本文將介紹消除鋸齒的方法,看看像素如何繪製。

我們所有的螢幕都是由我們所知道的像素構成。這些是巨大的方塊網格,每個網格都有紅、綠和藍 (RGB) 元件。遠處,我們可以看到圖片、文字和圖示,但是近距離可以看到 RGB 元件的格線和結構。

螢幕特寫的像素。每個像素都有紅色、綠色和藍色元件
圖 1:螢幕特寫的像素。每個像素都有紅色、綠色和藍色元件。

消除混疊

那麼,如果繪製向量形狀並通過像素的「部分」會發生什麼事呢?假設正在繪製的形狀是黑色,背景是白色。我們應該把像素都上色嗎?如果我們要調色,那應該是什麼顏色?黑色、灰色,還是其他?

像素化時,消除鋸齒程序會決定我們填入像素時應使用的顏色。最簡單的做法是採用灰階抵抗技術,這個像素的三個元件也同樣適用。因此,如果像素有一半,再假設像素寫為白色一秒以保持簡單,您就會覺得每個元件都會設為半亮度 (我知道的話),但其實比 Gamma 還複雜,也就是說您永遠不會將它設為確切的值。這當然會讓相關知識有點複雜,但這是關於我不會深入探討這個主題的簡介。值得一提的是,灰階反鋸齒能處理像素等級,實際上,這個效果也會大幅提升。

圖 2:消除鋸齒與堅硬邊緣
圖 2 - 消除鋸齒與硬邊緣

在圖 2 中,可以看到繪製的同一個三角形,但左側已啟用反鋸齒功能,右側則停用。如您所見,如果像素已啟用反鋸齒功能,當三角形只穿過一部分像素時,像素就會呈現灰色。不過如果停用,像素將以純黑色或純白色填滿,形狀看起來像鋸齒狀。

文字轉譯

每當瀏覽器在顯示文字 (基本上就是向量形狀) 時,就會遇到相同的問題:文字字元只會填滿部分像素,因此我們必須制定策略,指定如何填入這些像素。理想情況下,我們最好讓文字看起來更平易近人,讓閱讀起來更方便。

但後來,用灰階消除雜訊的方法僅止於一種方法。我們通常會採取更謹慎的方法來啟用像素的 RGB 元件。這個過程稱為子像素反鋸齒,而且多年來,Microsoft 的 ClearType 團隊尤其投入大量時間和精力來做到。如今這種技術的應用範圍越來越廣,所有主要瀏覽器也都擴大或更少。

首先,由於每個像素實際上都是由不同的紅色、綠色和藍色元件組成,因此我們會偵測個別元件應「開啟」的像素有多少。舉例來說,如果從左邊「覆蓋一半」的像素,我們可能完全將紅色元件切換為一半,同時將藍色元件保持關閉狀態。這個過程通常稱為「使螢幕的水平解析度變差」,然後把每個像素實際上是並排顯示的三個獨立元件,而非單一單位。

圖 3:使用灰階與子像素進行反鋸齒
圖 3 - 使用灰階與子像素進行反鋸齒

在上方圖 3 中,我們將以平等的方式處理每個元件,並平均開啟或關閉各元件 (灰階)。不過,我們則是使用子像素方法,並根據其與繪製形狀重疊的程度,讓每個元件 (紅色、綠色和藍色) 以不同的方式啟用。

不過,人類視覺能力實際上並未相等,對紅、綠和藍光的體重也不盡相同。我們對綠色技術的敏感度遠高於紅色或藍色,這表示雖然相較於灰階消除鋸齒,雖然知道還有一點好處,但就像 Darel Rex Finley 筆記一樣,在這種情況下,分別啟用每個元件並不會讓圖片清晰度提升 3 倍。不過,子像素反鋸齒絕對有所幫助,但這也代表我們看到的文字比使用灰階反鋸齒更為清楚。

圖 4 - 子像素反鋸齒文字。啟用像素的個別元件以創造整體效果
圖 4:子像素反鋸齒文字。啟用像素的個別元件以創造整體效果

挑戰追逐賽

這對開發人員有何影響?從 Chrome 的角度來看,至少在轉譯文字時使用了灰階和子像素反鋸齒功能,而所得到的,則取決於幾項條件。不過在開始之前,我們必須稍微瞭解圖層,因為這是播放的主要準則。如果您未曾瞭解 Chrome 內部使用的層次或它們在內部的應用方式,Tom Wiltzius 已為您寫了這個主題的一段簡介,您應該先閱讀。

假設您熟悉圖層或剛才讀過圖層,請繼續往下閱讀。網頁如已啟用硬體合成功能,但其中有文字內容「不是」根層的圖層,根據預設,這些內容都會以灰階反鋸齒方式轉譯。開發人員經常會注意到,如果他們會對元素套用各種入侵措施,將這些入侵手法擷取到專屬 (例如使用 TranslateZ) 的圖層,看到文字顯示的方式就會不一樣。開發人員經常透過 JavaScript 或 CSS 即時套用「新圖層」觸發條件,導致文字算繪從子像素切換為灰階。假如你不知道轉譯改變是什麼,可能會讓使用者感到困惑。不過,如果文字位於根圖層,應以子像素反鋸齒方式呈現,因此內容會清楚易讀。

但網路世界和任何事物一樣,情況都不斷在改變。只要圖層符合三項條件,就能在 Chrome 中為非根圖層的文字啟用子像素反鋸齒功能。值得一提的是,這些標準現在適用,但可能會有變動,我們日後應該也會推出更多案件。目前這些標準如下:

  1. 圖層的背景顏色完全不透明。值得注意的是,如果使用 border-radius 或非預設的 background-clip 值,圖層會視為非不透明,而文字算繪會還原為灰階反鋸。
  2. 圖層只能套用身分轉換或積分翻譯。這裡的分數是指四捨五入值。因此,舉例來說,translate(20.2px, 30px) 會產生灰階反鋸齒,因為 x 元件 20.2px 是非整合性質。身分轉換只是表示在預設的設定之外,不會額外套用旋轉、平移或縮放。
  3. 圖層的不透明度為 1.0。任何不透明度的任何變更都會從子像素變更為灰階。
圖 5 - 前後對照:灰階與子像素。注意文字右側的顏色標示
圖 5 - 前後對照:灰階與子像素。注意文字右側的顏色標示

最後請注意,套用 CSS 動畫可能會導致建立新圖層,而使用 requestAnimationFrame 則不會。對於部分開發人員而言,隱含 CSS 動畫的文字顯示差異。如果您因為文字顯示差異而用 JavaScript 為元素建立動畫,請確認這次更新能解決問題!

這就是 Chrome 的優勢。遠離其他瀏覽器的 Opera 和 Chromium 一樣,應該都能與 Chrome 的行為密切吻合。Internet Explorer 似乎對幾乎所有文字使用子像素反鋸齒 (如果您已啟用 ClearType!),雖然看似不在 Windows 8 的 Metro 模式中。鑒於 WebKit 距離 Blink 相近,所以 WebKit 的行為與 Chrome 非常類似,雖然沒有這些較新的改善項目,卻可以進行更多子像素消除。Firefox 的運作方式與 Internet Explorer insofar 相同,因為 Firefox 使用子像素反鋸齒技術處理幾乎所有文字。當然,這並非完整清單,而且所有瀏覽器中,都有可能會使用灰階反鋸齒選項,而不是子像素。不過別擔心,子像素反鋸齒技術也廣泛用於主要瀏覽器。

結語

現在,您已稍微瞭解消除鋸齒的運作方式,以及現今網站和應用程式中的文字轉譯方式的差異,尤其是在較低的 DPI 裝置上。如果您想瞭解 Chrome 的文字轉譯做法,請為下列錯誤加上星號:

資源與參考資料