跳转到内容

15 分钟 Quickstart

复制本页

这一步把旧中文手记中的“读取 → 处理 → 导出”结构整理成一个可对照的四个 binding 任务:把 input.jpg 缩小到不超过 640 × 640,不放大小图,输出质量为 82 的 output.webp。

运行示例时,可以将自己的 JPEG 命名为 input.jpg;尺寸和画面不同会产生不同的输出数据。

夜色中亮起红色轮廓灯的苏州东方之门建筑与前景步道
输入:JPEG1938 × 1292,610,191 bytes
缩小到 640 像素边界内的苏州东方之门夜景 WebP
参考输出:WebP640 × 427,36,172 bytes,quality 82

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

运行命令

go run . input.jpg output/

完整源码

package main

import (
	"fmt"
	"os"

	"github.com/davidbyttow/govips/v2/vips"
	"github.com/webp-sh/vips-handbook/examples/internal/recipeutil"
)

func main() {
	if err := run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run(args []string) error {
	if len(args) != 3 {
		return fmt.Errorf("usage: quickstart-thumbnail <input.jpg> <output-directory>")
	}
	inputPath, outputDir := args[1], args[2]
	if err := os.MkdirAll(outputDir, 0o755); err != nil {
		return err
	}

	if err := vips.Startup(nil); err != nil {
		return fmt.Errorf("start libvips: %w", err)
	}
	defer vips.Shutdown()

	image, err := vips.NewThumbnailFromFile(inputPath, 640, 640, vips.InterestingNone)
	if err != nil {
		return fmt.Errorf("create thumbnail: %w", err)
	}
	defer image.Close()

	output, err := recipeutil.ExportWebp(image, outputDir, "output.webp", 82, map[string]any{
		"width": 640, "height": 640, "crop": "none", "withoutEnlargement": true,
	})
	if err != nil {
		return err
	}
	if output.Width > 640 || output.Height > 640 {
		return fmt.Errorf("unexpected thumbnail dimensions: %dx%d", output.Width, output.Height)
	}
	if err := recipeutil.WriteResult(outputDir, "quickstart-thumbnail", inputPath, []recipeutil.Output{output}); err != nil {
		return err
	}

	fmt.Printf("quickstart-thumbnail: %dx%d, %d bytes\n", output.Width, output.Height, output.Size)
	return nil
}

至少确认 output.webp 存在且能被重新读取;宽和高都不超过 640;输入小于目标尺寸时没有被放大;输出格式确实是 WebP 而不是只改了扩展名。

  • Format: WEBP
  • Dimensions: 640 × 427
  • Bands: 3
  • Alpha: No
  • File size: 36,172 bytes
  • Generated with: govips v2.19.0 / libvips 8.17.3

四段代码表达同一个产品目标,但不是逐行等价:govips 和 pyvips 直接调用 thumbnail 能力,sharp 用 resize({ fit: 'inside' }) 表达边界,CLI 则通过操作参数传递保存选项。

继续阅读构建第一个完整图像 Pipeline,把输入检查、方向归一化、编码和结果验证拆成明确阶段。