跳转到内容

翻转(Flip)、画布扩展(Embed)与多图网格拼接

复制本页

除了缩放和裁剪,画布几何操作还包括三项高频任务:镜像翻转(Flip / Flop)、将图像嵌入更大画布并填充四周(Embed / Extend / Gravity),以及将多张图像拼接为长图或网格(Join / ArrayJoin)。

用于镜像翻转与画布操作的 1938×1292 夜景原图
输入原图:JPEG1938 × 1292
水平翻转后的 1938×1292 苏州东方之门夜景
水平镜像翻转:WebP1938 × 1292(govips 参考输出)

1. 水平与垂直翻转(注意 sharp 的命名差异)

Section titled “1. 水平与垂直翻转(注意 sharp 的命名差异)”

在 libvips 底层,翻转由 vips_flip(direction) 完成,方向枚举为 horizontal(左右镜像)与 vertical(上下镜像)。

// 水平翻转(左右镜像):支持 AccessSequential
if err := image.Flip(vips.DirectionHorizontal); err != nil {
return err
}
// 垂直翻转(上下镜像):需要随机访问或预先实体化缓冲
if err := image.Flip(vips.DirectionVertical); err != nil {
return err
}

2. 画布扩展与边缘延展模式(Embed / Gravity / extend)

Section titled “2. 画布扩展与边缘延展模式(Embed / Gravity / extend)”

当需要为图片四周加上固定像素的内边距(Padding),或者把横图放进正方形画布且不裁切原图(Letterboxing / Fit Contain)时,使用 vips_embed 或 vips_gravity。

libvips 支持 6 种填充新增画布区域的扩展策略(VipsExtend):

扩展策略 govips vips.ExtendStrategy sharp extendWith pyvips / vips CLI extend 填充效果
黑色填充 vips.ExtendBlack 'background'(默认黑) "black" 新增像素全为 0
白色填充 vips.ExtendWhite 'background'(配白底) "white" 新增像素全为最大值
指定背景色 EmbedBackground / EmbedBackgroundRGBA 'background' + background "background" + background=[...] 使用自定义 RGB/RGBA 填充
边缘像素复制拉伸 vips.ExtendCopy 'copy' "copy" 重复原图最外侧一圈像素
镜像反射延展 vips.ExtendMirror 'mirror' "mirror" 像镜子一样反射边缘画面
平铺重复 vips.ExtendRepeat 'repeat' "repeat" 将整张原图周期性重复平铺
// 方式 A:四周各扩充 40px 白边,总尺寸变为 (W+80)×(H+80)
w, h := image.Width(), image.Height()
bg := &vips.Color{R: 248, G: 250, B: 252}
if err := image.EmbedBackground(40, 40, w+80, h+80, bg); err != nil {
return err
}
// 方式 B:使用镜像边缘延展 (ExtendMirror)
if err := image.Embed(40, 40, w+80, h+80, vips.ExtendMirror); err != nil {
return err
}

3. 多图拼接与网格拼图(Join / ArrayJoin)

Section titled “3. 多图拼接与网格拼图(Join / ArrayJoin)”

当需要把两张图水平/垂直拼接成长图,或把一组缩略图排列成 N 列的雪碧图(Sprite Sheet)/ 宫格图时,使用 join 与 arrayjoin:

// 1. 两图水平或垂直拼接 (Join)
if err := leftImg.Join(rightImg, vips.DirectionHorizontal); err != nil {
return err
}
// 2. 多图按每行 2 列排列为网格 (ArrayJoin)
if err := tile1.ArrayJoin([]*vips.ImageRef{tile2, tile3, tile4}, 2); err != nil {
return err
}