跳转到内容

WebP 有损、无损、近无损(Near-Lossless)与编码开销调优

复制本页

WebP 同时具备基于 VP8 帧内预测的有损模式(Lossy)和基于 LZ77 + 熵编码的无损模式(Lossless),并且在有损与无损模式下都原生支持 8-bit Alpha 透明通道与多帧动画。

用于 WebP 编码对比的 1938×1292 夜景 JPEG 原图
输入:JPEG1938 × 1292,610,191 字节
以 Quality 82 导出的 1938×1292 WebP 图像
有损 WebP(Q=82):WebP1938 × 1292,402,162 字节(比原 JPEG 小 34.1%,含源 ICC)

许多开发者只知道 Quality 和 Lossless,却忽略了极适合 UI 截图与图表压缩的近无损模式(NearLossless):

  • 有损模式(Lossless = false):Quality 控制 VP8 量化步长(默认 75,常用 78 ~ 85)。
  • 纯无损模式(Lossless = true):像素 100% 恒等还原;此时 Quality 参数控制的是无损压缩搜索强度(数值越高压缩率越好但更慢)。
  • 近无损模式(NearLossless = true,无需手动设 Lossless = true):使用无损编码器,但在压缩前对像素做微小的阶梯预处理以抹平高频微噪点(Quality 在此模式下表示预处理精度,如 60 或 80),常能把 UI 截图体积再减小 30% ~ 50% 而肉眼几乎看不出差异。
参数项 govips WebpExportParams sharp .webp(options) pyvips / vips CLI webpsave 说明
质量 / 强度 Quality(0..100) quality(默认 80) Q=82 / --Q 82 有损下控制量化质量;近无损下控制像素预处理粒度
无损模式 Lossless: true lossless: true lossless=True / --lossless 开启 VP8L 无损编码
近无损模式 NearLossless: true nearLossless: true near_lossless=True / --near-lossless 在无损管线前做像素平滑预处理,适合图标与截图
CPU 编码档位 ReductionEffort(0..6,默认 4) effort(0..6,默认 4) effort=4 / --effort 4 0 最快但体积大;4 为线上默认平衡点;6 最慢
Alpha 通道质量 —(未暴露 alpha_q,默认 100) alphaQuality(0..100) alpha_q=90 / --alpha-q 90 有损 WebP 下将 alpha_q 设为 85~90 可显著缩减透明图体积
智能色度下采样 —(使用 libwebp 默认或 Preset) smartSubsample: true smart_subsample=True 高质量 YUV 4:2:0 色度下采样,改善红蓝边缘发虚(耗时增加)
元数据保留 Keep(ForeignKeep*) .keepIccProfile() 等 keep="icc" / --keep icc 各 binding 的默认值不同;govips v2.20 可组合 ICC、EXIF、XMP、IPTC 与 other
目标字节大小 TargetSize(字节数) — target_size / --target-size 版本敏感:需要底层 libvips >= 8.17.4

1. 有损摄影图与近无损 UI 图像代码示例

Section titled “1. 有损摄影图与近无损 UI 图像代码示例”
// 场景 A:摄影图有损 WebP(govips v2.20.0 未暴露 alpha_q,Alpha 按默认 100 编码)
lossy := vips.NewWebpExportParams()
lossy.Quality = 82
lossy.ReductionEffort = 4
lossy.StripMetadata = true
data, _, err := image.ExportWebp(lossy)
// 场景 B:UI 截图或透明图表采用近无损模式 (NearLossless)
nearLossless := vips.NewWebpExportParams()
nearLossless.NearLossless = true
nearLossless.Quality = 60 // 60 表示适度像素预处理以换取更高无损压缩率
nearLossless.ReductionEffort = 4
nlData, _, err := image.ExportWebp(nearLossless)

WebpExportParams.Keep 是元数据位掩码。零值表示未设置,此时 StripMetadata 继续决定是否剥离元数据;显式 Keep 则优先:

params := vips.NewWebpExportParams()
params.StripMetadata = true
params.Keep = vips.ForeignKeepIcc
data, _, err := image.ExportWebp(params)

在当前 v2.20.0 / libvips 8.17.3 基线上,默认 WebP 输出会保留源 ICC;ForeignKeepNone 删除全部元数据,ForeignKeepIcc 即使在 strip 模式下也保留 ICC。ForeignKeepGainmap 需要 libvips 8.18,本基线不会保留 gain map。sharp、pyvips 与 CLI 的开关和默认值仍需分别判断。

3. TargetSize 的 libvips 版本边界(8.17.4+)

Section titled “3. TargetSize 的 libvips 版本边界(8.17.4+)”

在 govips v2.19.0 的 WebpExportParams 中,新增了 TargetSize int 字段(对应 libvips webpsave 的 target_size 参数),用于指示编码器通过多趟迭代逼近指定的输出字节数上限。