什麼是 WebP?為什麼要使用這項功能?
WebP 是一種有損和無損壓縮方法,適用於網路上各種相片、半透明和圖像圖片。使用者可以調整有損壓縮的程度,在檔案大小和圖片品質之間取得平衡。WebP 的平均壓縮率通常比 JPEG 和 JPEG 2000 高出 30%,且不會降低圖片品質 (請參閱比較研究)。
WebP 格式的主要目標是製作更精美的小型圖片,藉此加快網頁載入速度。
哪些網路瀏覽器原生支援 WebP?
如要提升網站效能,網站管理員可以輕鬆為現有圖片建立最佳化的 WebP 替代版本,並根據目標對象,向支援 WebP 的瀏覽器提供這些圖片。
- 支援 WebP 有損壓縮
- Google Chrome (電腦版) 17 以上版本
- Android 版 Google Chrome 25 以上版本
- Microsoft Edge 18 以上版本
- Firefox 65 以上版本
- Opera 11.10 以上版本
- 原生網頁瀏覽器、Android 4.0 以上版本 (ICS)
- Safari 14 以上版本 (iOS 14 以上版本、macOS Big Sur 以上版本)
- 支援 WebP 有損、無損和 Alpha
- Google Chrome (電腦版) 23 以上版本
- Android 版 Google Chrome 25 以上版本
- Microsoft Edge 18 以上版本
- Firefox 65 以上版本
- Opera 12.10 以上版本
- 原生網路瀏覽器,Android 4.2 以上版本 (JB-MR1)
- Pale Moon 26 以上版本
- Safari 14 以上版本 (iOS 14 以上版本、macOS Big Sur 以上版本)
- 支援 WebP 動畫
- Google Chrome (電腦和 Android 版) 32 以上版本
- Microsoft Edge 18 以上版本
- Firefox 65 以上版本
- Opera 19 以上版本
- Safari 14 以上版本 (iOS 14 以上版本、macOS Big Sur 以上版本)
另請參閱:
如何偵測瀏覽器是否支援 WebP?
您只會向可正確顯示 WebP 圖片的用戶端提供這類圖片,並為無法顯示的用戶端改用舊版格式。幸好,無論是在用戶端或伺服器端,都有幾種偵測 WebP 支援的技術。部分 CDN 供應商會提供 WebP 支援偵測功能,做為服務的一部分。
透過 Accept 標頭進行伺服器端內容交涉
Web 用戶端通常會傳送「Accept」要求標頭,指出願意在回應中接受的內容格式。如果瀏覽器預先指出會「接受」image/webp 格式,網路伺服器就會知道可以安全地傳送 WebP 圖片,大幅簡化內容交涉程序。詳情請參閱下列連結。
Modernizr
Modernizr 是一個 JavaScript 程式庫,可方便地偵測網路瀏覽器是否支援 HTML5 和 CSS3 功能。尋找 Modernizr.webp、Modernizr.webp.lossless、Modernizr.webp.alpha 和 Modernizr.webp.animation 屬性。
HTML5 <picture>
元素
HTML5 支援 <picture>
元素,可讓您依優先順序列出多個替代圖片目標,以便用戶端要求第一個可正常顯示的候選圖片。請參閱 HTML5 Rocks 上的這項討論。<picture>
元素支援的瀏覽器越來越多。
在您自己的 JavaScript 中
另一種偵測方法是嘗試解碼使用特定功能的小型 WebP 圖片,並檢查是否成功。範例:
// check_webp_feature:
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
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];
}
請注意,圖片載入作業不會造成阻塞,而且是非同步作業。也就是說,任何依附於 WebP 支援的程式碼,最好都放在回呼函式中。
Google 為什麼要以開放原始碼形式發布 WebP?
我們深信開放原始碼模式的重要性。WebP 採用開放原始碼,因此任何人都能使用這個格式,並提出改進建議。我們相信在您的意見和建議下,WebP 圖像格式會隨著時間變得更加實用。
如何將個人圖片檔案轉換為 WebP 格式?
您可以使用 WebP 指令列公用程式,將個人圖片檔案轉換為 WebP 格式。詳情請參閱「使用 WebP」。
如果要轉換大量圖片,可以使用平台的殼層簡化作業。舉例來說,如要轉換資料夾中的所有 JPEG 檔案,請嘗試下列做法:
Windows:
> for /R . %I in (*.jpg) do ( cwebp.exe %I -o %~fnI.webp )
Linux / macOS:
$ for F in *.jpg; do cwebp $F -o `basename ${F%.jpg}`.webp; done
如何自行判斷 WebP 圖片品質?
目前,您可以將 WebP 檔案轉換為使用無損壓縮的常見格式 (例如 PNG),然後在任何瀏覽器或圖片檢視器中查看 PNG 檔案。如要快速瞭解 WebP 品質,請參閱這個網站的圖片庫,比較並排顯示的相片。
如何取得原始碼?
轉換器程式碼位於 WebP 開放原始碼專案頁面的下載部分。輕量型解碼器和 VP8 規格的程式碼位於 WebM 網站。如需容器規格,請參閱「RIFF 容器」頁面。
WebP 圖片的大小上限為何?
WebP 與 VP8 位元串流相容,且寬度和高度皆使用 14 位元。 WebP 圖片的像素尺寸上限為 16383 x 16383。
WebP 格式支援哪些色彩空間?
與 VP8 位元串流一致,有損 WebP 僅適用於 8 位元 Y'CbCr 4:2:0 (通常稱為 YUV420) 圖片格式。詳情請參閱 RFC 6386 的第 2 節「格式總覽」和「VP8 資料格式和解碼指南」。
無損 WebP 僅適用於 RGBA 格式。請參閱 WebP 無損位元串流規格。
為什麼無損 WebP 檔案與原始檔案不同?
Simple Encoding API 函式 (WebPEncodeLosslessRGB()
、WebPEncodeLosslessBGR()
、WebPEncodeLosslessRGBA()
、WebPEncodeLosslessBGRA()
) 會使用程式庫的預設設定。如果是無損壓縮,則表示「精確」已停用。全透明區域 (即 Alpha 值等於 0
的區域) 的 RGB 值會經過修改,以提升壓縮效果。如要避免這種情況,請使用 WebPEncode()
,並將 WebPConfig::exact
設為 1
。請參閱進階編碼 API 說明文件。
WebP 圖片會比來源圖片大嗎?
是,通常是從失真格式轉換為 WebP 無失真格式,或反向轉換時。這主要是因為色彩空間差異 (YUV420 與 ARGB) 和兩者之間的轉換。
一般來說,有以下三種情況:
- 如果來源圖片採用無損 ARGB 格式,空間降採樣至 YUV420 時,會產生新的顏色,這些顏色比原始顏色更難壓縮。如果來源是顏色不多的 PNG 格式,轉換為失真 WebP (或類似的失真 JPEG) 可能會導致檔案變大。
- 如果來源採用失真格式,使用無損 WebP 壓縮來擷取來源的失真特性,通常會產生較大的檔案。這並非 WebP 獨有的問題,例如將 JPEG 來源轉換為無損的 WebP 或 PNG 格式時,也可能發生這種情況。
- 如果來源採用有損格式,且您嘗試以較高的品質設定將其壓縮為有損 WebP,舉例來說,如果嘗試將畫質 80 的 JPEG 檔案轉換為畫質 95 的 WebP 檔案,即使兩種格式都會造成失真,轉換後的檔案通常也會比較大。評估來源品質通常是不可能的,因此建議您降低目標 WebP 品質,如果檔案大小持續較大,另一種做法是避免使用品質設定,改為使用
cwebp
工具中的-size
選項或對等 API,以指定檔案大小為目標。舉例來說,以原始檔案大小的 80% 為目標,可能更為穩健。
請注意,將 JPEG 來源轉換為有損的 WebP,或將 PNG 來源轉換為無損的 WebP,不會發生檔案大小突然變大的情況。
WebP 是否支援漸進式或交錯式顯示?
WebP 不提供 JPEG 或 PNG 意義上的漸進式或交錯式解碼重新整理。因為每次重新整理事件都會完整傳遞至解壓縮系統,這可能會對解碼用戶端的 CPU 和記憶體造成過大壓力。
平均而言,解碼漸進式 JPEG 圖片相當於解碼基準圖片 3 次。
或者,WebP 提供漸進式解碼,盡快使用所有可用的位元串流輸入位元組,嘗試產生可顯示的樣本列。這不僅能節省用戶端的記憶體、CPU 和重新繪製作業,還能提供下載狀態的視覺提示。如要使用遞增解碼功能,請透過進階解碼 API 存取。
如何在 Android 專案中使用 libwebp Java 繫結?
WebP 支援 JNI 繫結,可繫結至 swig/
目錄中的簡易編碼器和解碼器介面。
在 Eclipse 中建構程式庫:
- 請確認您已安裝 ADT 外掛程式,並正確設定 NDK 工具和 NDK 路徑 (依序點選「Preferences」 >「Android」 >「NDK」)。
- 建立新專案:依序點選「File」 >「New」 >「Project」 >「Android Application Project」。
- 複製或將 libwebp 解壓縮至新專案中名為
jni
的資料夾。 - 將
swig/libwebp_java_wrap.c
新增至LOCAL_SRC_FILES
清單。 - 以滑鼠右鍵按一下新專案,然後依序選取「Android Tools」 >「Add Native Support ...」,將程式庫納入建構作業。
開啟專案屬性,然後依序前往「C/C++ Build」 >「Behaviour」。將
ENABLE_SHARED=1
新增至Build (Incremental build)
區段,將 libwebp 建構為共用程式庫。注意:一般而言,設定
NDK_TOOLCHAIN_VERSION=4.8
可提升 32 位元建構作業的效能。將
swig/libwebp.jar
新增至libs/
專案資料夾。建構專案。這會建立
libs/<target-arch>/libwebp.so
。使用
System.loadLibrary("webp")
在執行階段載入程式庫。
請注意,程式庫可透過 ndk-build
和內含的 Android.mk
手動建構。在這種情況下,您可以重複使用上述部分步驟。
如何透過 C# 使用 libwebp?
WebP 可以建構為 DLL,並匯出 libwebp API。然後即可在 C# 中匯入這些函式。
建構 libwebp.dll。這會正確設定 WEBP_EXTERN,以匯出 API 函式。
libwebp> nmake /f Makefile.vc CFG=release-dynamic
將 libwebp.dll 新增至專案,並匯入所需函式。 請注意,如果您使用簡易 API,應呼叫
WebPFree()
來釋放傳回的緩衝區。[DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] static extern int WebPEncodeBGRA(IntPtr rgba, int width, int height, int stride, float quality_factor, out IntPtr output); [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] static extern int WebPFree(IntPtr p); void Encode() { Bitmap source = new Bitmap("input.png"); BitmapData data = source.LockBits( new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr webp_data; const int size = WebPEncodeBGRA(data.Scan0, source.Width, source.Height, data.Stride, 80, out webp_data); // ... WebPFree(webp_data); }
為什麼要使用動畫 WebP?
與 GIF 動畫相比,WebP 動畫的優點
WebP 支援 24 位元 RGB 顏色和 8 位元 Alpha 管道,相較之下,GIF 僅支援 8 位元顏色和 1 位元 Alpha。
WebP 支援有損和無損壓縮,事實上,單一動畫可以結合有損和無損影格。GIF 僅支援無損壓縮。WebP 的有損壓縮技術非常適合從真實世界影片建立動畫圖片,而這類動畫圖片的來源越來越受歡迎。
WebP 所需的位元組比 GIF 少1。 轉換為有損 WebP 的動畫 GIF 檔案會縮小 64%,轉換為無損 WebP 的檔案則會縮小 19%。這在行動網路上尤其重要。
有搜尋動作時,WebP 解碼所需的時間較短。在 Blink 中,捲動或變更分頁可能會隱藏及顯示圖片,導致動畫暫停,然後跳轉至其他時間點。CPU 使用率過高導致動畫掉格時,解碼器也可能需要向前搜尋動畫。在這些情境中,動態 WebP 的總解碼時間2是 GIF 的 0.57 倍,因此捲動時較不會發生延遲,且 CPU 使用率尖峰過後能更快恢復。這是因為 WebP 比 GIF 多了兩項優點:
WebP 圖片會儲存每個影格是否包含 Alpha 的中繼資料,因此不需要解碼影格即可判斷。這有助於更準確地推斷特定影格所依附的先前影格,進而減少先前影格的不必要解碼作業。
與現代影片編碼器類似,WebP 編碼器會定期加入關鍵影格 (大多數 GIF 編碼器不會這麼做)。大幅提升長動畫的搜尋體驗。為方便插入這類影格,且不會大幅增加圖片大小,WebP 除了 GIF 使用的影格處置方法外,還為每個影格新增了「混合方法」標記。這樣一來,即使前一個影格並非全尺寸,關鍵影格也能繪製圖像,就像整個圖像已清除為背景顏色一樣。
與 GIF 動畫相比,WebP 動畫的缺點
如果沒有搜尋,WebP 的直線解碼比 GIF 更耗用 CPU。有損 WebP 的解碼時間是 GIF 的 2.2 倍,無損 WebP 則是 1.5 倍。
WebP 的支援範圍遠不及 GIF,後者幾乎是通用格式。
在瀏覽器中新增 WebP 支援功能會增加程式碼占用空間和攻擊面。在 Blink 中,這大約是 1500 行額外程式碼 (包括 WebP demux 程式庫和 Blink 端 WebP 圖片解碼器)。請注意,如果 WebP 和 WebM 共用更多常見的解碼程式碼,或是 WebP 的功能併入 WebM,日後這個問題可能會減少。
為何不直接在 <img>
中支援 WebM?
從長遠來看,支援 <img>
標記內的影片格式可能較為合理。不過,如果現在就這麼做,並打算讓 <img>
中的 WebM 填補動畫 WebP 的角色,會有以下問題:
解碼依附於先前影格的影格時,WebM 需要的記憶體比 WebP 動畫多 50%,才能保留最少數量的先前影格3。
瀏覽器和裝置支援的視訊轉碼器和容器差異很大。為方便自動轉碼內容 (例如節省頻寬的 Proxy),瀏覽器需要新增 Accept 標頭,指出圖片標記支援的格式。即使這樣可能仍不夠,因為「video/webm」或「video/mpeg」等 MIME 類型仍未指出轉碼器支援 (例如 VP8 與 VP9)。另一方面,WebP 格式實際上已凍結,如果出貨的供應商同意出貨動畫 WebP,所有 UA 的 WebP 行為應會一致;由於「image/webp」接受標頭已用於表示 WebP 支援,因此不需要新的接受標頭變更。
Chromium 影片堆疊經過最佳化,可流暢播放影片,並假設一次只播放一或兩部影片。因此,實作作業會積極消耗系統資源 (執行緒、記憶體等),盡可能提升播放品質。這類實作方式無法順利擴充至多個同步影片,且需要重新設計,才能適用於圖片量大的網頁。
WebM 目前並未納入 WebP 的所有壓縮技術。因此,這張圖片以 WebP 壓縮時,效果明顯優於其他替代格式:
1 為了比較 GIF 動畫和 WebP 動畫,我們從網路上隨機選取約 7000 張 GIF 動畫圖片。這些圖片是使用「gif2webp」工具,以預設設定 (從 2013 年 10 月 8 日的最新 libwebp 來源樹狀結構建構) 轉換為 WebP 動畫。比較數字是這些圖片的平均值。
2 解碼時間是使用 2013 年 10 月 8 日的最新 libwebp + ToT Blink,透過基準測試工具計算得出。「解碼時間 (含搜尋)」的計算方式為「解碼前五個影格、清除影格緩衝區快取、解碼後五個影格,依此類推」。
3 WebM 會在記憶體中保留 4 個 YUV 參考影格,每個影格會儲存 (寬度 + 96)*(高度 + 96) 像素。如果是 YUV 4:2:0,每 6 個像素需要 4 個位元組 (或每像素 3/2 個位元組)。因此,這些參照影格會使用 4*3/2*(width+96)*(height+96)
位元組的記憶體。另一方面,WebP 只需要提供前一個影格 (以 RGBA 格式),也就是 4*width*height
位元組的記憶體。
4 動畫 WebP 必須使用 Google Chrome 32 以上版本