常见问题解答

什么是 WebP?为什么我应该使用它?

WebP 是一种有损和无损压缩方法,可用于网上的各种照片、半透明和图形图片。有损压缩的角度是可调整的,以便用户在文件大小和图片质量之间进行权衡。WebP 的压缩率通常比 JPEG 和 JPEG 2000 平均高出 30%,而又不会降低图片质量(请参阅比较研究)。

WebP 格式的主要目的是创建更小、更美观的图片,从而帮助提高 Web 的速度。

哪些网络浏览器本身支持 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)
    • 满月 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”请求标头,以表明他们愿意接受哪些内容格式作为响应。如果浏览器预先表明自己会“接受”图片/webp 格式,网络服务器就会知道自己可以安全地发送 WebP 图片,从而极大简化了内容协商。如需了解详情,请访问以下链接。

现代风味

Modernizr 是一个用于轻松检测网络浏览器中 HTML5 和 CSS3 功能支持的 JavaScript 库。查找 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

如果要转换许多映像,您可以使用平台的 shell 来简化操作。例如,如需转换文件夹中的所有 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 图片能否大于其源图片?

可以,通常在从有损格式转换为 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 和重绘工作,同时提供有关下载状态的视觉提示。增量解码功能可通过 Advanced Decoding API 获得。

如何在我的 Android 项目中使用 libwebp Java 绑定?

WebP 支持 JNI 绑定到 swig/ 目录中的简单编码器和解码器接口。

Eclipse 中构建库:

  1. 确保随 NDK 工具一起安装 ADT 插件,并且 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 ...,将该库添加到您的 build 中。
  6. 打开项目属性,然后转到 C/C++ Build > Behaviour。将 ENABLE_SHARED=1 添加到 Build (Incremental build) 部分,以将 libwebp 构建为共享库。

    注意:设置 NDK_TOOLCHAIN_VERSION=4.8 通常会提高 32 位 build 性能。

  7. swig/libwebp.jar 添加到 libs/ 项目文件夹中。

  8. 构建您的项目。这将创建 libs/<target-arch>/libwebp.so

  9. 在运行时使用 System.loadLibrary("webp") 加载库。

请注意,您可以使用 ndk-build 和其中包含的 Android.mk 手动构建该库。在这种情况下,可以重复使用上述某些步骤。

如何将 C# 与 libwebp 搭配使用?

可将 WebP 构建为导出 libwebp API 的 DLL。这些函数随后可以使用 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 支持 8 位 Alpha 通道的 24 位 RGB 颜色,而 GIF 的 8 位颜色和 1 位的 Alpha 通道则是 8 位的。

  2. WebP 支持有损和无损压缩;事实上,单个动画可以结合使用有损帧和无损帧。GIF 仅支持无损压缩。WebP 的有损压缩技术非常适合基于现实世界视频(越来越多的动画图片来源)制作的动画图片。

  3. WebP 需要的字节数少于 GIF1。转换为有损 WebP 的 GIF 动画尺寸缩小 64%,而无损 WebP 缩小 19%。这对于移动网络尤为重要。

  4. 有跳转时,WebP 可缩短解码的时间。在 Blink 中,滚动或更改标签页可以隐藏和显示图片,导致动画先暂停再跳到其他时间点。导致 CPU 丢弃帧的 CPU 使用率过高也可能需要解码器在动画中前进。在这些情况下,动画 WebP 的总时长为 GIF 的 0.57 倍2,从而减少了滚动时的卡顿现象,并从 CPU 利用率峰值中更快地恢复。这是因为 WebP 比 GIF 具有两个优势:

    • WebP 图片会存储有关每个帧是否包含 Alpha 值的元数据,这样就无需解码帧即可做出此决定。这样可以更准确地推断指定帧依赖于之前的哪些帧,从而减少对之前帧进行不必要的解码。

    • 就像现代视频编码器一样,WebP 编码器会以启发方式定期添加关键帧(大多数 GIF 编码器不会这样做)。这可以显著改善在长动画中跳转的进度。为了在不显著增加图片大小的情况下插入此类帧,除了 GIF 使用的帧处理方法之外,WebP 还为每个帧添加了“混合方法”标志。这样,关键帧可以像整个图片已被清除为背景颜色一样进行绘制,而不强制上一帧为完整尺寸。

与动画 GIF 相比,WebP 的缺点

  1. 在缺少跳转功能的情况下,WebP 的直线解码比 CPU 更耗费 CPU 资源。有损 WebP 的解码时间是 GIF 的 2.2 倍,而无损 WebP 的解码时间是 GIF 的 1.5 倍。

  2. WebP 支持并不像 GIF 支持那么普遍,后者实际上是通用的。

  3. 为浏览器添加 WebP 支持会增加代码占用空间和攻击面。在 Blink 中,额外添加大约 1500 行代码(包括 WebP 多路分配库和 Blink 端 WebP 图片解码器)。请注意,如果 WebP 和 WebM 共用更常见的解码代码,或者 WebP 的功能被纳入到 WebM 中,那么将来可能会降低此问题。

为什么不直接在 <img> 中支持 WebM?

从长远来看,支持 <img> 标记中的视频格式可能是合理的。不过,为了实现 <img> 中的 WebM 可以填充动画 WebP 的建议角色,现在要这样做就有问题:

  1. 在解码依赖于旧帧的帧时,若要保留之前帧的最少数量,WebM 需要比动画 WebP 多出 50% 的内存3

  2. 视频编解码器和容器支持因浏览器和设备而异。为方便内容自动转码(例如,为了节省带宽的代理),浏览器需要添加接受标头,以指明其图片代码支持的格式。甚至可能不够,因为“video/webm”或“video/mpeg”等 MIME 类型仍不表示支持编解码器(例如 VP8 与 VP9)。另一方面,WebP 格式实际上已被冻结,如果提供该协议的供应商同意发布动画 WebP,所有 UA 中的 WebP 行为都应保持一致;由于“image/webp”accept 标头已用于指示支持 WebP,因此无需更改新的 Accept 标头。

  3. Chromium 视频堆栈经过优化,可流畅播放,并且假定一次只播放一两个视频。因此,该实现会消耗系统资源(线程、内存等)来最大限度地提高播放质量。此类实现无法很好地扩展到多个同步视频,需要重新设计才能与包含大量图片的网页配合使用。

  4. WebM 目前并未采用 WebP 的所有压缩方法。因此,与替代图片相比,此图片在 WebP 中的压缩效果明显更好:


1 对于动画 GIF 与动画 WebP 之间的所有比较,我们使用了从网络中随机获取的大约 7000 张动画 GIF 语料库。这些图片是使用“gif2webp”工具(采用最新的 libwebp 源代码树,自 2013 年 10 月 8 日起构建而成)的默认设置转换为动画 WebP。比较数字是这些图片的平均值。

2 截至 2013 年 10 月 8 日,使用最新的 libwebp + TT 链接使用基准工具计算了解码时间。“通过跳转解码时间”的计算公式为:“对前 5 帧进行解码,清除帧缓冲区缓存,对接下来 5 帧进行解码,等等”。

3 WebM 在内存中保留 4 个 YUV 参考帧,其中每个帧存储 (width+96)*(height+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 及更高版本