常見問題

什麼是 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.webpModernizr.webp.losslessModernizr.webp.alphaModernizr.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) 和兩者之間的轉換。

一般來說,有以下三種情況:

  1. 如果來源圖片採用無損 ARGB 格式,空間降採樣至 YUV420 時,會產生新的顏色,這些顏色比原始顏色更難壓縮。如果來源是顏色不多的 PNG 格式,轉換為失真 WebP (或類似的失真 JPEG) 可能會導致檔案變大。
  2. 如果來源採用失真格式,使用無損 WebP 壓縮來擷取來源的失真特性,通常會產生較大的檔案。這並非 WebP 獨有的問題,例如將 JPEG 來源轉換為無損的 WebP 或 PNG 格式時,也可能發生這種情況。
  3. 如果來源採用有損格式,且您嘗試以較高的品質設定將其壓縮為有損 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 中建構程式庫:

  1. 請確認您已安裝 ADT 外掛程式,並正確設定 NDK 工具和 NDK 路徑 (依序點選「Preferences」 >「Android」 >「NDK」)。
  2. 建立新專案:依序點選「File」 >「New」 >「Project」 >「Android Application Project」
  3. 複製或將 libwebp 解壓縮至新專案中名為 jni 的資料夾。
  4. swig/libwebp_java_wrap.c 新增至 LOCAL_SRC_FILES 清單。
  5. 以滑鼠右鍵按一下新專案,然後依序選取「Android Tools」 >「Add Native Support ...」,將程式庫納入建構作業。
  6. 開啟專案屬性,然後依序前往「C/C++ Build」 >「Behaviour」。將 ENABLE_SHARED=1 新增至 Build (Incremental build) 區段,將 libwebp 建構為共用程式庫。

    注意:一般而言,設定 NDK_TOOLCHAIN_VERSION=4.8 可提升 32 位元建構作業的效能。

  7. swig/libwebp.jar 新增至 libs/ 專案資料夾。

  8. 建構專案。這會建立 libs/<target-arch>/libwebp.so

  9. 使用 System.loadLibrary("webp") 在執行階段載入程式庫。

請注意,程式庫可透過 ndk-build 和內含的 Android.mk 手動建構。在這種情況下,您可以重複使用上述部分步驟。

如何透過 C# 使用 libwebp?

WebP 可以建構為 DLL,並匯出 libwebp API。然後即可在 C# 中匯入這些函式。

  1. 建構 libwebp.dll。這會正確設定 WEBP_EXTERN,以匯出 API 函式。

    libwebp> nmake /f Makefile.vc CFG=release-dynamic
    
  2. 將 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 動畫的優點

  1. WebP 支援 24 位元 RGB 顏色和 8 位元 Alpha 管道,相較之下,GIF 僅支援 8 位元顏色和 1 位元 Alpha。

  2. WebP 支援有損和無損壓縮,事實上,單一動畫可以結合有損和無損影格。GIF 僅支援無損壓縮。WebP 的有損壓縮技術非常適合從真實世界影片建立動畫圖片,而這類動畫圖片的來源越來越受歡迎。

  3. WebP 所需的位元組比 GIF 少1。 轉換為有損 WebP 的動畫 GIF 檔案會縮小 64%,轉換為無損 WebP 的檔案則會縮小 19%。這在行動網路上尤其重要。

  4. 有搜尋動作時,WebP 解碼所需的時間較短。在 Blink 中,捲動或變更分頁可能會隱藏及顯示圖片,導致動畫暫停,然後跳轉至其他時間點。CPU 使用率過高導致動畫掉格時,解碼器也可能需要向前搜尋動畫。在這些情境中,動態 WebP 的總解碼時間2是 GIF 的 0.57 倍,因此捲動時較不會發生延遲,且 CPU 使用率尖峰過後能更快恢復。這是因為 WebP 比 GIF 多了兩項優點:

    • WebP 圖片會儲存每個影格是否包含 Alpha 的中繼資料,因此不需要解碼影格即可判斷。這有助於更準確地推斷特定影格所依附的先前影格,進而減少先前影格的不必要解碼作業。

    • 與現代影片編碼器類似,WebP 編碼器會定期加入關鍵影格 (大多數 GIF 編碼器不會這麼做)。大幅提升長動畫的搜尋體驗。為方便插入這類影格,且不會大幅增加圖片大小,WebP 除了 GIF 使用的影格處置方法外,還為每個影格新增了「混合方法」標記。這樣一來,即使前一個影格並非全尺寸,關鍵影格也能繪製圖像,就像整個圖像已清除為背景顏色一樣。

與 GIF 動畫相比,WebP 動畫的缺點

  1. 如果沒有搜尋,WebP 的直線解碼比 GIF 更耗用 CPU。有損 WebP 的解碼時間是 GIF 的 2.2 倍,無損 WebP 則是 1.5 倍。

  2. WebP 的支援範圍遠不及 GIF,後者幾乎是通用格式。

  3. 在瀏覽器中新增 WebP 支援功能會增加程式碼占用空間和攻擊面。在 Blink 中,這大約是 1500 行額外程式碼 (包括 WebP demux 程式庫和 Blink 端 WebP 圖片解碼器)。請注意,如果 WebP 和 WebM 共用更多常見的解碼程式碼,或是 WebP 的功能併入 WebM,日後這個問題可能會減少。

為何不直接在 <img> 中支援 WebM?

從長遠來看,支援 <img> 標記內的影片格式可能較為合理。不過,如果現在就這麼做,並打算讓 <img> 中的 WebM 填補動畫 WebP 的角色,會有以下問題:

  1. 解碼依附於先前影格的影格時,WebM 需要的記憶體比 WebP 動畫多 50%,才能保留最少數量的先前影格3

  2. 瀏覽器和裝置支援的視訊轉碼器和容器差異很大。為方便自動轉碼內容 (例如節省頻寬的 Proxy),瀏覽器需要新增 Accept 標頭,指出圖片標記支援的格式。即使這樣可能仍不夠,因為「video/webm」或「video/mpeg」等 MIME 類型仍未指出轉碼器支援 (例如 VP8 與 VP9)。另一方面,WebP 格式實際上已凍結,如果出貨的供應商同意出貨動畫 WebP,所有 UA 的 WebP 行為應會一致;由於「image/webp」接受標頭已用於表示 WebP 支援,因此不需要新的接受標頭變更。

  3. Chromium 影片堆疊經過最佳化,可流暢播放影片,並假設一次只播放一或兩部影片。因此,實作作業會積極消耗系統資源 (執行緒、記憶體等),盡可能提升播放品質。這類實作方式無法順利擴充至多個同步影片,且需要重新設計,才能適用於圖片量大的網頁。

  4. 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 以上版本