本文首發於微信公眾號:大遷世界, 我的微信:qq449245884,我會第一時間和你分享前端行業趨勢,學習途徑等等。
更多開源作品請看 GitHub https://github.com/qq449245884/xiaozhi ,包含一線大廠面試完整考點、資料以及我的系列文章。
谷歌最初開發的WebP是一種取代JPEG的有損影像格式,它能夠產生比以JPEG編碼的同等質量的影像檔案更小的檔案。後來,該格式的更新引入了無失真壓縮、類似PNG的阿爾法通道透明度和類似GIF的動畫等選項,所有這些都可以與JPEG式的有失真壓縮同時使用。WebP是一種非常多才多藝的格式。
WebP的有失真壓縮演算法基於VP8影片編解碼器用於壓縮影片關鍵幀的方法。從高層次來看,它類似於JPEG編碼:WebP以“塊”為單位操作,而不是單個畫素,並且具有類似亮度和色度之間的分割。WebP的亮度塊為16x16
,色度塊為8x8
,並且這些“macroblocks”進一步細分為4x4子塊。
WebP與JPEG根本不同的兩個特徵是“塊預測(block prediction)”和“自適應塊量化(adaptive block quantization)”。
Block Prediction
塊預測是指根據其周圍塊的值,特別是上方和左側的塊,預測每個色度和亮度塊的內容的過程。正如你所想象的那樣,執行這項工作的演算法相當複雜,但用簡單的語言來說,“如果當前塊上方和左側是藍色的,則假定該塊是藍色的。”
實際上,PNG和JPEG也在某種程度上進行這種預測。然而,WebP獨特之處在於它取樣周圍塊的資料,然後透過幾種不同的“預測模式”嘗試填充當前塊,有效地嘗試“繪製”影像的缺失部分。然後,每個預測模式提供的結果將與實際影像資料進行比較,選擇最接近的預測匹配。
當然,即使最接近的預測匹配也不會完全正確,因此該塊的預測值與實際值之間的差異被編碼到檔案中。在解碼影像時,渲染引擎使用相同的資料應用相同的預測邏輯,從而針對每個塊生成相同的預測值。然後將編碼在檔案中的預期影像與預測之間的差異應用於預測值 - 類似於Git提交代表一個差異補丁,被應用在本地檔案上,而不是一個全新的檔案副本。
舉個例子:我們不想深入瞭解真正的預測演算法中涉及的複雜數學問題,因此我們將發明一個類似於 WebP 的編碼方式,其中包含單個預測模式,並像使用舊格式一樣有效地傳遞數字網格。我們的演算法有一個稱為“預測模式一”的單個預測模式:每個塊的值是它上面和左邊的塊的值之和,從1開始。
現在,假設我們從下面的真實影像資料開始:
111151111
122456389
使用我們的預測模型來確定2x9
網格的內容,我們會得到以下結果:
111111111
123456789
我們的資料很適合我們發明的預測演算法--預測的資料與我們的真實資料非常吻合。當然,並不是完全吻合--實際資料有幾個塊與預測資料不同。因此,我們傳送的編碼不僅包括要使用的預測方法,還包括任何與預測值不同的塊的差異。
_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _
使用預測模式一的2x9網格。+4到1x5,-1到2x3,-4到2x7。
最終的結果是一個令人難以置信的高效編碼檔案。
自適應塊狀量化
JPEG壓縮是一個統一的操作,對影像中的每個塊應用相同的量化級別。對於具有均勻組成的影像,這當然是有道理的——但現實世界中的照片並不比我們周圍的世界更加均勻。實際上,這意味著我們的JPEG壓縮設定不是由高頻細節(JPEG壓縮擅長的部分)決定的,而是由我們的影像中最有可能出現壓縮偽影的部分決定的。
在這個的例子中所看到的,前景中蝴蝶的翅膀看起來相對清晰——與高解析度原始影像相比略微有點顆粒感,但如果沒有原始影像來比較,幾乎不會引起注意。同樣,蜜蜂花的花序和前景中的葉子——即使把壓縮級別調得超過合理水平,你和我也可能能看出一些壓縮偽影,但前景中的東西看起來依然過得去。而圖片左上角的低頻資訊——模糊的綠色背景葉子——看起來很糟糕。即使是一個沒有經過專業訓練的觀眾也會立即注意到質量問題——背景中微妙的漸變被壓縮成了鋸齒狀、純色的塊。
為了避免這種情況,WebP採用了自適應的量化方法:影像被分成最多四個視覺上相似的部分,並獨立調整這些部分的壓縮引數。使用WebP進行同樣過度的壓縮:
這兩個影像檔案的大小大致相同。當我們看蝴蝶的翅膀時,它們的質量大致相同——如果你非常仔細地觀察,你可以看到一些微小的差異,但總體上沒有實質性的質量差異。在WebP中,蜜蜂草的花朵只是略微更清晰一些——同樣,除非你將兩者並排比較並真正尋找質量上的差異,否則很可能察覺不出來。然而,背景則完全不同:它幾乎沒有JPEG明顯的偽影。WebP給我們相同的檔案大小,但是更高質量的影像——除了一些我們的心理視覺系統如果不是這樣緊密比較就無法察覺到的微小細節。
使用 WebP
WebP的內部機制可能比JPEG編碼要複雜得多,但對於我們日常工作而言同樣簡單:WebP的所有編碼複雜性都規範化為一個單一的“quality”值,從0到100表示,就像JPEG一樣。同樣,這並不意味著你只能使用一個整體“quality”設定。您可以 - 也應該 - 調整WebP編碼的所有細節,即使只是為了更好地理解這些通常看不見的設定如何影響檔案大小和質量。
谷歌提供了一個名為cwebp
的命令列編碼器,可以讓你轉換或壓縮單個檔案或整個影像目錄:
$ cwebp -q 80 butterfly.jpg -o butterfly.webp
Saving file 'butterfly.webp'
File: butterfly.jpg
Dimension: 1676 x 1418
Output: 208418 bytes Y-U-V-All-PSNR 41.00 43.99 44.95 41.87 dB
(0.70 bpp)
block count: intra4: 7644 (81.80%)
Intra16: 1701 (18.20%)
Skipped: 63 (0.67%)
bytes used: header: 249 (0.1%)
mode-partition: 36885 (17.7%)
Residuals bytes |segment 1|segment 2|segment 3|segment 4| total
macroblocks: | 8%| 22%| 26%| 44%| 9345
quantizer: | 27 | 25 | 21 | 13 |
filter level: | 8 | 6 | 19 | 16 |
如果你不傾向於使用命令列,Squoosh也可以為我們提供WebP編碼。它讓我們可以選擇在不同的編碼、設定、質量水平和檔案大小與JPEG的差異之間進行並排比較。
程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:https://web.dev/learn/images/...
交流
有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。