原文地址:www.smashingmagazine.com/2009/07/15/clever-png-optimization-techniques
作者:sergey chikuyonok
做為一名網頁設計師你或許已經對png格式非常熟悉,它提供了完整的透明度,這是一種無損的,功能強大的圖像格式。能夠很好代替gif圖像格式。但是絕大多數人認為它不可被壓縮,帶著這樣的疑問我們來認真看完下面這篇文章。每一種圖像格式都有自己的優缺點,如果掌握了相關知識,在進行圖像優化時能夠針對圖像進行相應處理,得到高品質的圖像和高壓縮率,這是圖像優化的關鍵所在。png被稱為開源的gif圖像格式,它們之間有很多相同的地方(如:索引色),但png在每一個方面都要強于gif。它介紹了一些非常酷的功能,例如:圖像封裝和壓縮,但對我們網頁設計師來說最重要的還是線性過濾(也稱為“三角過濾”)。
這里介紹下它的原理,假如我們有一張5*5像素水平漸變的圖片,如下圖(每個數字代表了一種顏色)
通過上圖你會發現相同的顏色都是在垂直方向上擴展,而不是水平方向。這樣的圖片如果用gif格式將很難獲得高壓縮率,它只壓縮水平方向擴展的顏色(圖像尺寸越大,越能說明問題)。讓我們看看線性過濾是怎樣將這類圖像壓縮的:
以數字2為標識的每一行都經過了“up過濾”,“up過濾”向 png 解碼器發送信息:“對于當前的像素,提取上方像素的值,并將其添加到當前值”。圖中第2-5行垂直方向都擁有相同的值。所以它們的值都是0,如果這樣的圖片越大那么壓縮比率也越大。
在理想情況下,“sub過濾”能提供更好的結果:
以數字1為標識的每一行都經過了“sub過濾”,它發送信息給解碼器:“當前像素提取左側像素的值,添加到當前值”。例子中的值全為1,我想你大概也猜到這樣的數據肯定能被有效的壓縮。
線性過濾是非常重要的概念,尤其是在圖片處理時可以針對過濾特點進行處理以便得到更好的過濾效果。png有5種過濾器:none(無過濾),sub(當前值減去左側像素的值),up(減去上方像素的值),average(減去左側和上方像素的平均值)和paeth(替換上方,左邊或者上方的左邊像素值,并重新以alan paeth命名)。
通過比較下面的圖片,我想大家應該都能明白“線性過濾”的魅力所在。
gif:2568字節
png:372字節
png是一種存儲元數據信息的圖片類型。如果你是photoshop用戶,你應該已經對png8(索引圖像)和png24(真彩色圖像)非常熟悉,如果你是 fireworks用戶,或許已經知道png32(真彩色透明圖像)。但是photoshop的png24格式也能存儲真彩色透明圖像,其實這些命名都不是官方的,所以在png圖像格式說明面并不能找到這些概念,為了方便起見,在這次討論中我們采用photoshop的命名方式。
png 可提供5種圖片類型:灰度,真彩色,索引色,帶alpha通道的灰度,帶alpha通道的真彩色。遺憾的是photoshop只能導出3種圖像類型:帶透明的索引顏色,真彩色,帶透明度的真彩色。這就是為什么大家一直認為fireworks是png圖像最好處理工具。其實不然,fireworks并沒有足夠的工具來處理導出的png圖像,它僅僅是在導出時做一些微小的優化工作。
那還有沒有更好的png壓縮工具呢?答案是肯定的。optipng和pngcrush都是非常有效的工具,從本質上來看,這些工具主要做以下優化:
所有這些操作都不會影響到圖像質量,卻能減小 png 圖像文件的大小,所以我強烈建議您每次保存 png 圖像時都使用這些工具。
下面來介紹幾種處理圖像的方法,使圖片更好的執行“線性過濾”。
色調分離的優化方法已經廣為人知。在photoshop中打開樣例圖片,點擊圖層面板中的”創建新的填充或調整圖層圖標”,并選擇色調分離:
選擇盡可能小的數值(通常40就夠了)并保存圖片:
原圖:84k
壓縮后:53k
優化原理:有效的減少色彩數,合并相似的顏色,創建出色調區域,更好的執行“線性過濾”,得到高壓縮率。
這種方法有一定的局限性,尤其是優化的圖片與 html 背景融合的情況下須慎用(藍色為 html 背景)。
看看下面的圖片:
75k
30k
兩張圖片都是用 photoshop 導出的,而且沒有經過任何優化。即使對比圖中的每個像素,你都不會發現它們之間存在任何區別。但是為什么前者居然是后者的2.5倍大?
在探尋奧秘之前,你必須安裝一個“remove transparency”的 photoshop 插件才可以看到隱藏的細節。
在 photoshop 中打開上面的兩張圖片,選擇 filer -> photo wiz -> remove trasparency。現在,你就可以看到保存在圖像中的真實像素信息了:
這是怎么回事?其實很簡單。帶alpha通道的真彩色圖像每個像素都用了4個字節來表示:rgba。最后一個是alpha通道,控制該像素透明度:值為0則完全透明,255則完全不透明。這意味著每一個像素(任何rgb值)只要alpha值設為0就可以完全隱藏。但是這些rgb數據仍然存在,而且它不利于png編碼器對數據流進行有效的封裝和編碼。因此,我們必須在導出圖像前刪除這些隱藏數據(例如上圖中填充的黑色)。下面是一個比較便捷的方法:
對于上述這些操作我們只須了解即可,因為png二次壓縮工具內已經內置了該項操作。
有時候因為圖片中存在一些半透明像素,你不得不保存一個“重量級”的png-24文件。如果將此類圖像一分為二,一部分是不透明像素,另一部分則為半透明,然后各以適當格式保存。比如你可以用 png-24 格式保存半透明像素,而不透明像素則用 png-8 甚至 jpeg 格式保存。這樣操作下來在實際應用中你將會節省很大的圖片流量。看一下實際案例:
png24 62k
png-8 17kb
png-24 色調分離(色階=35) 6kb
最終對比結果:
原圖:63k
優化后:23kb
優化后的圖片大小幾乎只有原圖的1/3,在原來的基礎上能夠節省2/3的流量。但是這種方法有一個明顯的缺點:將一個圖片分成兩個圖片,增加了重構人員的工作量,減少圖片大小的同時卻又增加了http連接數。
這里只是介紹些優化方法,在實際應用中請大家多去嘗試,發現不同方法的應用規律,總結出來大家一起分享! 在原文中sergey chikuyonok提到還會有第二部分的內容,將進一步探討更高層次的技術,會談到灰度模式的圖像,使用更少的顏色,降低細節,并討論進一步優化png的小技巧,以及png優化的實例。讓我們一起期待下一篇大作。
新聞熱點
疑難解答