圖像優(yōu)化原理,原來(lái)這么簡(jiǎn)單
我們都喜歡有圖片的網(wǎng)頁(yè),圖片很美好,很有趣,同時(shí)它涵蓋了豐富的信息。所以,在加載網(wǎng)頁(yè)時(shí),大部分流量被圖像資源所占據(jù)(平均60%,數(shù)據(jù)可能不準(zhǔn)確)。
圖像資源不只占用網(wǎng)絡(luò)資源,它也會(huì)占用網(wǎng)頁(yè)中大量的視覺(jué)空間。所以圖像渲染的速度會(huì)直接影響用戶體驗(yàn)。圖像優(yōu)化其實(shí)就是最大限度地減少圖像的字節(jié)數(shù),從而最大化地縮減網(wǎng)絡(luò)資源占用,使瀏覽器下載速度變的更快。下載速度越快,在屏幕上渲染的時(shí)間就越早,所以視覺(jué)上就會(huì)有一個(gè)更好的體驗(yàn)。
當(dāng)然,優(yōu)化圖像最佳的方式就是不用圖像,例如使用CSS效果(漸變,陰影,圓角等)代替圖像。使用CSS比同等視覺(jué)效果的圖像資源的字節(jié)數(shù)要小非常多,這是毋庸置疑的。另一個(gè)好處是CSS不受分辨率影響,使用CSS渲染出的視覺(jué)效果可以在任何分辨率和縮放級(jí)別下始終清晰地顯示。
但必須使用圖像資源時(shí),對(duì)圖像進(jìn)行合理的優(yōu)化將對(duì)性能有著至關(guān)重要的影響。
本文不會(huì)介紹如何進(jìn)行圖像優(yōu)化,有大量在線工具和開源項(xiàng)目供我們使用,使用起來(lái)非常的簡(jiǎn)單。本文將重點(diǎn)介紹圖像優(yōu)化的原理。
首先,本文會(huì)介紹兩種圖像資源:矢量圖與柵格圖(位圖),并分別介紹優(yōu)化它們的原理。隨后介紹無(wú)損壓縮與有損壓縮以及它們的區(qū)別。在本文的最后,我們會(huì)介紹什么是高分辨率屏幕。
希望通過(guò)本篇文章的介紹,可以讓您對(duì)圖像優(yōu)化的原理有一個(gè)直觀的感受。
1. 矢量圖與柵格圖(位圖)
矢量圖與柵格圖(位圖)是兩種不同的圖像格式。
圖1-1 矢量圖與柵格圖
矢量圖形是計(jì)算機(jī)圖形學(xué)中用點(diǎn)、直線或者多邊形等基于數(shù)學(xué)方程的幾何圖元表示圖像。
柵格圖(英語(yǔ):Raster graphics),又稱位圖(Bitmap)或點(diǎn)陣圖,是使用像素陣列(Pixel-array/Dot-matrix點(diǎn)陣)來(lái)表示的圖像。
以矢量圖為例,程序繪制一個(gè)半徑為r的圓所需的主要信息是:
半徑r
圓心坐標(biāo)
輪廓樣式與顏色(可能是透明)
填充樣式與顏色(可能是透明)
矢量圖的內(nèi)容是這些繪制相關(guān)的關(guān)鍵信息,同樣的圖像如果是柵格圖(位圖),則圖像是由稱作像素的單個(gè)點(diǎn)組成的。
柵格圖的每個(gè)像素都分配有特定的位置和顏色值。每個(gè)像素的顏色信息由RGB組合或者灰度值表示。
根據(jù)位深度,可將柵格圖分為1、4、8、16、24及32位圖像等。每個(gè)像素使用的信息位數(shù)越多,可用的顏色就越多,顏色表現(xiàn)就越逼真。當(dāng)然,相應(yīng)的數(shù)據(jù)量就越大,圖像所占字節(jié)數(shù)也就越大。
那什么是位深度呢?位深度也叫做色彩深度或者色彩位數(shù),即柵格圖中要用多少個(gè)二進(jìn)制位來(lái)表示每個(gè)點(diǎn)的顏色,色彩深度越高,每個(gè)像素點(diǎn)可用的顏色就越多。色彩深度是用“n位顏色”(n-bit colour)來(lái)說(shuō)明的。若色彩深度是n位,即有2^n種顏色選擇,而儲(chǔ)存每像素所用的位數(shù)就是n。例如,位深度為 1 的像素柵格圖只有兩個(gè)可能的值(黑色和白色),所以又稱為二值柵格圖。位深度為 8 的圖像有 2^8(即 256)個(gè)可能的值。
所以矢量圖對(duì)比柵格圖的優(yōu)點(diǎn)主要在以下幾點(diǎn):
保存最少的信息,文件字節(jié)數(shù)比柵格圖小,且文件大小與物體的大小無(wú)關(guān)
任意放大矢量圖形,不會(huì)丟失細(xì)節(jié)或影響清晰度,因?yàn)槭噶繄D形是與分辨率無(wú)關(guān)的
在放大的時(shí)候,直線與曲線都不會(huì)成比例地變粗,它只會(huì)保持不變或者要小于縮放比例
保存的物體參數(shù)可以在后面修改。也就是說(shuō)物體的運(yùn)動(dòng)、縮放、旋轉(zhuǎn)、填充等都不會(huì)降低繪制的精度。
但每一種格式都有優(yōu)缺點(diǎn),矢量圖適用于簡(jiǎn)單的幾何圖像,如果是場(chǎng)景復(fù)雜的照片,矢量格式就不能滿足要求了,因?yàn)槊枋鏊行螤钏璧?SVG 標(biāo)記量可能高得離譜。即便如此,輸出效果可能仍然無(wú)法達(dá)到“照片級(jí)真實(shí)感”,所以這種情況使用柵格圖顯然更合適。
因?yàn)闁鸥駡D是由很多個(gè)像素點(diǎn)組成的,所以當(dāng)我們放大柵格圖時(shí),我們會(huì)看到圖形會(huì)出現(xiàn)鋸齒并且模糊不清(因?yàn)橄袼攸c(diǎn)被放大了),所以我們?cè)谑褂脰鸥駡D時(shí),需要根據(jù)不同的屏幕分辨率來(lái)保存多個(gè)版本的柵格圖圖像,這樣可以提供最佳的用戶體驗(yàn)。
現(xiàn)在我們已經(jīng)了解了什么是矢量圖與柵格圖,接下來(lái)我們將介紹如何優(yōu)化它們。
2. 優(yōu)化矢量圖
SVG大家應(yīng)該都不陌生,它是一種可縮放矢量圖形。前不久我在寫 《嗨,送你一張Web性能優(yōu)化地圖》 這篇文章時(shí),@安佳 姐姐幫我畫了一張SVG圖。
圖2-1 SVG示例圖
圖2-1您可以通過(guò)點(diǎn)擊鏈接在瀏覽器打開它,然后查看網(wǎng)頁(yè)源代碼,在源碼中可以看到它涵蓋了大量的元數(shù)據(jù),例如圖層信息、注解和 XML 命名空間等,而瀏覽器渲染時(shí)通常不需要這些數(shù)據(jù)。
我們可以通過(guò)svgo之類的工具將 SVG 文件縮小。
上面這張圖片,我使用svgo優(yōu)化完之后,文件大小縮減了69.3%!原圖16.315 KiB優(yōu)化后文件大小5.009 KiB。您可以點(diǎn)擊鏈接在瀏覽器打開優(yōu)化后的SVG矢量圖,并查看網(wǎng)頁(yè)源代碼,對(duì)比它們之間的區(qū)別,您可以看到源代碼明顯少了很多,但并不影響瀏覽器正常渲染。
3. 優(yōu)化柵格圖
通過(guò)第一小節(jié)的介紹,我們大致可以想象出,其實(shí)柵格圖是二維“像素”柵格。例如一個(gè)10*10像素的圖像是 100 個(gè)像素序列,而每個(gè)像素中又存儲(chǔ)了RGBA值(R紅色通道、G綠色通道、B藍(lán)色通道、A alpha透明度通道)。
在內(nèi)部,瀏覽器會(huì)為每個(gè)通道分配 256 個(gè)值(色階),就是說(shuō)每個(gè)通道 8 位(因?yàn)?^8=256),那么一個(gè)像素有四個(gè)通道(RGBA),所以每個(gè)像素一共 32 位(4 個(gè)通道 * 8 位 = 32 位),32 位 = 4 字節(jié),也就是說(shuō)每個(gè)像素 4 占個(gè)字節(jié)。所以,只要我們知道柵格圖尺寸,我們就可以輕易地計(jì)算出圖像文件的大小。
從上表可以看到,隨著圖片尺寸的變大,文件大小會(huì)以驚人的速度暴增。
再基于此特征的前提下,我們應(yīng)該怎樣改善柵格圖的文件大小以獲得更快的加載速度呢?
在第一小節(jié)中,我們簡(jiǎn)單介紹了”色彩深度“,所以一個(gè)簡(jiǎn)單的策略是我們可以通過(guò)調(diào)整圖像的色彩深度來(lái)降低圖像文件的大小。每個(gè)通道 8 位為每個(gè)通道提供 256 個(gè)值,RGB三個(gè)通道一共可以為每個(gè)像素提供 16777216 種顏色(256^3=16777216)。如果我們將色彩深度調(diào)整為 RGB 通道一共只需要 8 位,那么加上 Alpha 透明度通道的 8 位,一共為 16 位,也就是說(shuō)每個(gè)像素兩個(gè)字節(jié)(16位 = 2個(gè)字節(jié)),與原來(lái)每個(gè)像素 4 個(gè)字節(jié)相比,節(jié)約了 50% 的字節(jié)!
但是你一定會(huì)有疑問(wèn),顏色值少了那么多,圖像的質(zhì)量會(huì)不會(huì)變得很差?我們可以用一張圖來(lái)對(duì)比一下。
圖3-1 不同色彩深度的圖片進(jìn)行對(duì)比
這張圖是上個(gè)月(2018-10)我去參加W3C TPAC會(huì)議時(shí)在法國(guó)讓彭星小哥哥幫我拍攝的。這張圖包含漸變色過(guò)渡的復(fù)雜場(chǎng)景(天空),可以看到,調(diào)整了色彩深度后,從肉眼上看到的視覺(jué)差異并不明顯。
在優(yōu)化了各個(gè)像素中存儲(chǔ)的數(shù)據(jù)之后,我們還可以更進(jìn)一步。事實(shí)上,許多圖像的相鄰像素都具有相似的顏色,壓縮程序可以利用這個(gè)特征采用“增量編碼”的方式對(duì)圖像進(jìn)行壓縮。在這種編碼方式下,并不為每個(gè)像素單獨(dú)存儲(chǔ)值,而是存儲(chǔ)相鄰像素之間的差異,如果相鄰像素相同,則增量為“零”,只需存儲(chǔ)一位即可。通過(guò)存儲(chǔ)數(shù)據(jù)之間的差異,而不是存儲(chǔ)數(shù)據(jù)本身,這樣的方式可以大幅減少數(shù)據(jù)的重復(fù),從而降低文件大小。
當(dāng)然,圖像壓縮領(lǐng)域的解決方案還遠(yuǎn)不止這些,因?yàn)閳D像占據(jù)了網(wǎng)絡(luò)世界中大量的字節(jié),所以好的圖像壓縮方法具有極大的價(jià)值,這一領(lǐng)域?qū)W術(shù)性很強(qiáng),我們也沒(méi)有能力去發(fā)明新的算法,但了解這一領(lǐng)域的基本概念還是可以的,例如本文介紹的 RGBA 像素、色彩深度和各種優(yōu)化方法。
4. 無(wú)損壓縮與有損壓縮
無(wú)損數(shù)據(jù)壓縮(Lossless Compression)指數(shù)據(jù)經(jīng)過(guò)壓縮后,信息不受損失,還能完全恢復(fù)到壓縮前的原樣。
那么無(wú)損壓縮是如何做到保存完整的原始信息的同時(shí)降低文件大小的呢?
舉個(gè)例子:一張圖是由100個(gè)紅點(diǎn)構(gòu)成,那么正常情況下它會(huì)以類似“紅點(diǎn)、紅點(diǎn)、...(重復(fù)97次)...、紅點(diǎn)”的格式來(lái)存儲(chǔ)它(柵格圖的存儲(chǔ)格式我們?cè)诒疚牡牡谌」?jié)中介紹過(guò))。為了降低文件大小,我們可以改成用“100個(gè)紅點(diǎn)”這樣的格式來(lái)存儲(chǔ)這張圖片,這樣就可以在不失去任何信息的情況下完成壓縮,這就是無(wú)損壓縮。
但如果想保存文件的所有信息,那么無(wú)論使用任何壓縮方法,文件大小都無(wú)法低于一個(gè)下界。舉個(gè)例子:壓縮后得到的zip文件會(huì)比源文件更小,但一直重復(fù)壓縮同一個(gè)文件并不會(huì)讓文件大小變成0,因?yàn)樵次募K究含有一定的數(shù)據(jù)量。
這個(gè)時(shí)候,使用有損壓縮可以突破這個(gè)限制。
因?yàn)槿说娜庋酆茈y觀察到一張高分辨率圖像里面的一些細(xì)節(jié),所以舍棄這些人類無(wú)法察覺(jué)的細(xì)節(jié),就可以用更小的數(shù)據(jù)量提供與原始數(shù)據(jù)相差無(wú)幾的感官體驗(yàn)(當(dāng)然也可以更進(jìn)一步,例如:通過(guò)失去一部分可以察覺(jué)的細(xì)節(jié),來(lái)達(dá)到更好的壓縮率),這就是有損壓縮。有損數(shù)據(jù)壓縮又稱破壞性資料壓縮、不可逆壓縮。有損數(shù)據(jù)壓縮是將次要的信息數(shù)據(jù)舍棄,犧牲一些質(zhì)量來(lái)減少數(shù)據(jù)量,提高壓縮比。
有損壓縮的一個(gè)優(yōu)點(diǎn)是在有些情況下,它能夠獲得比任何已知無(wú)損壓縮小得多的文件大小,同時(shí)又能滿足系統(tǒng)的需要。
總結(jié)
本文重點(diǎn)介紹了什么是矢量圖與柵格圖(位圖),以及各種圖片優(yōu)化工具是如何優(yōu)化它們的。
最后,我們還討論了什么是有損壓縮與無(wú)損壓縮,以及它們之間的區(qū)別。
作者:berwin
歡迎關(guān)注微信公眾號(hào) :前端陽(yáng)光