跳转到内容

缩放、裁剪、旋转与翻转

复制本页

几何处理首先要明确输出画布:目标宽高是多少、是否允许裁剪、超出原图时如何填充、方向是否已按 EXIF Orientation 归一化。下面按变体分节,每个几何操作单独展示其输出和对应代码。

所有变体使用同一张输入图:

用于几何变换的苏州东方之门夜景原图
输入:JPEG1938 × 1292,610,191 bytes

参考输出由 govips v2.19.0 / libvips 8.17.3 实际生成。

将输入缩小到 400 × 400 边界内,不放大小图。下列代码动态计算缩放因子,并把最小边钳制在 1.0 以避免放大。

缩小到 400 像素边界内的苏州东方之门夜景
resize-fit:WebPfit inside 400 × 400,不放大小图
func scale(image *vips.ImageRef) float64 {
s := 400.0 / float64(image.Width())
if hs := 400.0 / float64(image.Height()); hs < s {
s = hs
}
if s > 1.0 {
s = 1.0
}
return s
}
终端窗口
# 在 run() 内:vips.Startup(nil) 并 defer vips.Shutdown();
image, err := vips.NewImageFromFile("input.jpg")
if err != nil { return err }
defer image.Close()
s := scale(image)
if err := image.Resize(s, vips.KernelLanczos3); err != nil { return err }
data, _, err := image.ExportWebp(vips.NewWebpExportParams())
if err != nil { return err }
return os.WriteFile("resize-fit.webp", data, 0o644)

从左上角坐标 (520, 250) 取出 500 × 500 的正方形区域。裁剪前应验证矩形不越界。

从夜景原图中裁剪出的 500 像素正方形建筑细节
坐标裁剪:WebPleft 520、top 250、500 × 500
image, err := vips.NewImageFromFile("input.jpg")
if err != nil { return err }
defer image.Close()
if err := image.ExtractArea(520, 250, 500, 500); err != nil { return err }
data, _, err := image.ExportWebp(vips.NewWebpExportParams())
if err != nil { return err }
return os.WriteFile("crop.webp", data, 0o644)

将图像顺时针旋转 30 度。任意角度旋转需要插值,可能扩大画布并引入背景区域,这里用深色 #1d2d35 填充扩展部分。

顺时针旋转 30 度并以深色填充扩展画布的夜景
旋转:WebP30°,深色背景,#1d2d35
image, err := vips.NewImageFromFile("input.jpg")
if err != nil { return err }
defer image.Close()
if err := image.Similarity(1, 30, &vips.ColorRGBA{R: 29, G: 45, B: 53, A: 255}, 0, 0, 0, 0); err != nil { return err }
data, _, err := image.ExportWebp(vips.NewWebpExportParams())
if err != nil { return err }
return os.WriteFile("rotate-30.webp", data, 0o644)

沿水平轴翻转图像,输出画布尺寸不变。

水平翻转后的苏州东方之门夜景
水平翻转:WebP输出画布 1938 × 1292
image, err := vips.NewImageFromFile("input.jpg")
if err != nil { return err }
defer image.Close()
if err := image.Flip(vips.DirectionHorizontal); err != nil { return err }
data, _, err := image.ExportWebp(vips.NewWebpExportParams())
if err != nil { return err }
return os.WriteFile("flip-horizontal.webp", data, 0o644)

不同变体对画布大小和背景的选择不同:fit 保持原比例缩小,crop 固定取区域,旋转可能需要扩展画布并填色。生产环境应针对输出画布、背景策略和兴趣区域显式决策,而不是依赖 binding 默认值。

  • 未验证裁剪边界:越界 extract_area 会返回错误。
  • 依赖默认缩放:只传两个数字而不指定 fit/cover/inside,不同 binding 默认不同。
  • 忽略背景颜色:透明输出与不支持 Alpha 的格式需要不同的旋转背景处理。