WebP 技術(shù)原理及應(yīng)用

1.背景

瀏覽器環(huán)境下,使用最多的圖片格式有 JPEG、PNG、GIF。其中,JPEG 適合色彩復(fù)雜的圖片,PNG 適合色彩單一或者需要透明的圖片,GIF 通常用于動(dòng)圖?,F(xiàn)有的圖片格式體積較大。


圖1.1- 微店模板編輯頁瀑布圖

從瀑布圖可見,圖片的加載在整個(gè)頁面加載時(shí)間中占據(jù)了很大的比重,個(gè)別 JPEG 圖片甚至達(dá) 200 多 KB,這在移動(dòng)端環(huán)境下非常影響用戶體驗(yàn)。

2.介紹

WebP 是一個(gè)現(xiàn)代的圖片格式,用于在 web 上提供更好的有損和無損壓縮圖片。它能夠在肉眼觀看幾乎一樣的情況下,對(duì)圖片體積進(jìn)行大幅壓縮。在將一張 1.3MB 的 JPG 有損壓縮為 WebP 后,大小僅為483KB。你能分辨出下面兩張圖片有什么差別嗎?


圖2.1

圖2.2

我們來測(cè)試一下 JPG 和 PNG 轉(zhuǎn)成 WebP 后,實(shí)際體積大概減少多少。

根據(jù)測(cè)試結(jié)果可見,對(duì) PNG 進(jìn)行 WebP 無損壓縮后,體積減少了 31%,這與 Google 宣稱的 26% 大體吻合。WebP 有損壓縮的減少比例則更大,將圖片質(zhì)量降低到原來的 75% 后,減少體積達(dá) 90% 左右。值得注意的是,將 JPG 進(jìn)行 WebP 無損壓縮后,圖片大小反而增加了 66%。在實(shí)際應(yīng)用中,推薦使用 WebP 有損壓縮。

另外,WebP 支持 alpha 透明和 24bit 顏色數(shù),不存在 PNG8 色彩不夠豐富和毛邊問題。WebP 也支持真彩動(dòng)圖。因此 WebP 可以替代當(dāng)前大多數(shù)圖片格式,包括 JPG、PNG、GIF 等。

3.原理

下面來分析一下 WebP 有損壓縮的編碼過程:
1. 分塊(MacroBlocking)
將圖片劃分成多個(gè)宏塊(macro blocks),典型的宏塊由一個(gè) 16×16 的亮度像素(luma pixel)塊和兩個(gè) 8×8 的色度像素(chroma pixel)塊組成。分塊越小,預(yù)測(cè)越準(zhǔn),需要記錄的信息也越多。一般來說,細(xì)節(jié)越豐富的地方,分塊越細(xì),即使用 4×4 分塊預(yù)測(cè)。細(xì)節(jié)相對(duì)不豐富的地方使用 16×16 分塊。(這一過程相當(dāng)于 JPEG 編碼中的色彩空間轉(zhuǎn)換)

圖3.1-分塊

2. 幀內(nèi)預(yù)測(cè)
WebP 有損壓縮使用了幀內(nèi)預(yù)測(cè)編碼,這一技術(shù)也被用于 VP8 視頻編碼中的關(guān)鍵幀壓縮。VP8 有四種常見的幀內(nèi)預(yù)測(cè)模型。

  • H_PRED(horizontal prediction)
    像素塊中每一行使用其左邊一列(col L)的數(shù)據(jù)填充(如圖3.2 Horizontal)
  • V_PRED (vertical prediction)
    像素塊中每一列使用其上邊一行(row A)的數(shù)據(jù)填充(如圖3.2 Vertical)
  • DC_PRED (DC prediction)
    像素塊中每個(gè)單元使用 row A 和 col L 的所有像素的平均值填充(如圖3.2 Average)
  • TM_PRED (TrueMotion prediction)
    一種我還沒搞清楚的預(yù)測(cè)模式,比較接近真實(shí)數(shù)據(jù)

下圖展示了 4×4 分塊的所有幀內(nèi)預(yù)測(cè)模型


圖 3.2 - VP8 幀內(nèi)預(yù)測(cè)模型

使用哪種分塊預(yù)測(cè)模式是動(dòng)態(tài)決定的。編碼器會(huì)將所有可能的預(yù)測(cè)模式都計(jì)算出來,然后選出錯(cuò)誤程度最小的模式。

3. DCT(離散余弦變換)
將預(yù)測(cè)部分的原圖像數(shù)據(jù)減去預(yù)測(cè)出來的數(shù)據(jù),得到差值矩陣,最后對(duì)差值進(jìn)行 DCT。此步驟會(huì)生成一個(gè)頻率系數(shù)矩陣,左上的系數(shù)幅度最大,右下最小。幅度值越小,頻率越高。大部分圖片信息都在左上區(qū)域。這一步的作用就是找出圖片的高頻和低頻區(qū)域。

4. 量化
人眼對(duì)高頻部分不敏感,這一步會(huì)將高頻部分舍去。對(duì)上一步的頻率系數(shù)表和量化表進(jìn)行計(jì)算,將頻率系數(shù)表和量化表按位相除,并四舍五入位整數(shù)。最終生成一個(gè)量化矩陣。

5. 算法編碼
WebP使用 Arithmetic entropy encoding,該算法相比JPEG上使用的 Huffman encoding,在壓縮表現(xiàn)上更出色。

圖 3.3 - WebP 無損壓縮過程

總結(jié)一下,WebP 對(duì)圖片進(jìn)行分塊,然后對(duì)待填充的宏塊使用了幀間預(yù)測(cè)技術(shù),根據(jù)其附近已編碼宏塊的數(shù)據(jù),預(yù)測(cè)出當(dāng)前塊數(shù)據(jù)。相比 JEPG 對(duì)圖像原值進(jìn)行編碼,WebP 編碼的是預(yù)測(cè)值和原值的差值,這是 WebP 體積更小的主要原因。最后,WebP 使用了更優(yōu)秀的算數(shù)編碼。

4.應(yīng)用

圖 4.1 - WebP 兼容性

WebP 完全兼容 Android 4.4 及其以上版本,而在另一大移動(dòng)平臺(tái) iOS 上,則是完全不兼容 WebP。因此,我們需要在前端進(jìn)行平臺(tái)檢測(cè),對(duì)于支持 WebP 的平臺(tái)輸出 WebP,在不支持的平臺(tái)上采用降級(jí)方案。

方案一:
JavaScript 判斷瀏覽器是否支持 WebP。

function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

如果平臺(tái)支持 WebP,則在請(qǐng)求頭 Accept 中帶上 image/webp,這樣服務(wù)器就會(huì)知道瀏覽器是否支持 WebP。

方案二:
Google 開發(fā)的 PageSpeed 模塊,可以自動(dòng)將圖像轉(zhuǎn)出 WebP 或者其他格式。以 Nginx 為例。
首先在 http 模塊中開啟 pagespeed 屬性。

pagespeed on;
pagespeed FileCachePath "/var/cache/ngx_pagespeed/“;

然后在你的主機(jī)配置添加如下一行代碼,就能啟用這個(gè)特性。

pagespeed EnableFilters convert_png_to_jpeg,convert_jpeg_to_webp;

我們可以看下經(jīng)過轉(zhuǎn)換后的代碼:
頁面原始代碼:

圖 4.2 - 原始代碼

Chrome 打開后源碼如下:

圖 4.3 - Chrome 下的代碼

Safari 打開如下:

圖 4.4 - Safari 下的代碼

5.總結(jié)

顯然,WebP 是個(gè)好東西,它在肉眼效果幾乎一樣的情況下,大幅減少了圖片體積。本文對(duì) WebP 這種圖片格式進(jìn)行了性能測(cè)試分析,并解釋了 WebP 有損壓縮的實(shí)現(xiàn)原理,最后給出了兩種應(yīng)用方案。


參考文獻(xiàn):

  1. https://isux.tencent.com/introduction-of-webp.html
  2. https://developers.google.com/speed/webp/docs/compression#adaptive_block_quantization
  3. https://medium.com/@duhroach/how-webp-works-lossly-mode-33bd2b1d0670
  4. https://modpagespeed.com/doc/configuration
  5. https://juejin.im/entry/5791843bc4c9710054f55751
  6. https://aotu.io/notes/2016/06/23/explore-something-of-webp/index.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容