高效缩略图(Thumbnail)与解码期收缩
在生产环境中生成缩略图时,不要先用 NewImageFromFile 完整解码原图再调用 Resize。libvips 专门提供了 thumbnail 管线,能够在解码格式容器的同时执行块级下采样(Shrink-on-load),将内存峰值与 CPU 消耗降低一个数量级。


四入口可执行缩略图代码
Section titled “四入口可执行缩略图代码”下面的代码将 1938 × 1292 的 JPEG 缩放到 640 × 427 边界内(仅缩小、不放大,SizeDown / withoutEnlargement: true),并以 WebP Quality 82 导出:
package main
import ( "fmt" "os"
"github.com/davidbyttow/govips/v2/vips")
func main() { if err := vips.Startup(nil); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer vips.Shutdown()
// 直接从文件走 Thumbnail 管线,启用解码期收缩 (Shrink-on-load) image, err := vips.NewThumbnailWithSizeFromFile( "input.jpg", 640, 427, vips.InterestingNone, vips.SizeDown, ) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer image.Close()
params := vips.NewWebpExportParams() params.Quality = 82 data, _, err := image.ExportWebp(params) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if err := os.WriteFile("output.webp", data, 0o644); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) }}import sharp from 'sharp';
// sharp 的 resize() 默认开启 fastShrinkOnLoad: trueawait sharp('input.jpg') .resize(640, 427, { fit: 'inside', withoutEnlargement: true, fastShrinkOnLoad: true, }) .webp({ quality: 82 }) .toFile('output.webp');import pyvips
# 直接使用 Image.thumbnail,而非 new_from_file().thumbnail_image()image = pyvips.Image.thumbnail( "input.jpg", 640, height=427, size="down", crop="none",)image.write_to_file("output.webp", Q=82)#!/usr/bin/env bashset -euo pipefail
vips thumbnail input.jpg 'output.webp[Q=82]' 640 --height 427 --size down --crop none为什么 Thumbnail 远快于 Load + Resize
Section titled “为什么 Thumbnail 远快于 Load + Resize”vips_thumbnail 在底层串联了五步针对大图缩略优化的操作:
- 格式感知解码期收缩(Shrink-on-load):
- JPEG:利用 libjpeg 的 DCT 分块特性,在反离散余弦变换阶段直接按
1/2、1/4或1/8尺寸解码。例如将4000 × 3000的 JPEG 缩到400 × 300时,libjpeg 直接输出1000 × 750像素,跳过了 93% 的全分辨率像素解码。 - WebP / HEIF / AVIF:利用解码器内置的缩放解码能力或直接提取内嵌缩略图。
- SVG / PDF:根据目标宽高反推所需的渲染 DPI,避免先光栅化成巨幅位图再缩小。
- 金字塔 TIFF / OpenSlide:直接挑选分辨率最接近目标尺寸的子层级(Sub-IFD)。
- JPEG:利用 libjpeg 的 DCT 分块特性,在反离散余弦变换阶段直接按
- 盒式整数倍预缩小(
vips_shrink):将像素快速块平均到略大于目标尺寸的中间分辨率。 - 预乘 Alpha 与高质量抗锯齿核(
vips_reduce):若含透明通道,自动先预乘 Alpha,再用 Lanczos3 核精确缩放到目标尺寸,最后反预乘,避免半透明边缘产生黑边。 - EXIF 方向自动修正:在缩放管线中自动根据 EXIF Orientation 旋转到正方向,无需额外调用全图旋转。
- 色彩空间感知:可配合输入/输出 ICC Profile 在标准色彩空间下完成插值。
尺寸约束策略(Size)对照
Section titled “尺寸约束策略(Size)对照”生成缩略图时,通常需要控制“当原图比目标框更小时是否允许放大”:
| 行为意图 | govips vips.Size |
sharp ResizeOptions |
pyvips / vips CLI size |
|---|---|---|---|
| 仅缩小,不放大小图(生产推荐) | vips.SizeDown |
withoutEnlargement: true |
"down" / --size down |
| 既可缩小也可放大 | vips.SizeBoth |
默认行为(两项均为 false) |
"both" / --size both |
| 仅放大,不缩小大图 | vips.SizeUp |
withoutReduction: true |
"up" / --size up |
| 忽略原宽高比强制拉伸 | vips.SizeForce |
fit: 'fill' |
"force" / --size force |
- 如果需要对比
fit inside与cover画布策略,请参阅缩放:fit、cover 与裁剪位置。 - 如果需要根据画面内容自动寻找裁剪中心或去除白边,请参阅智能裁剪(Smart Crop)、焦点与自动去白边。