Go语言开发实现一个图片批量压缩工具
作者:程序员爱钓鱼
在日常开发和办公中,图片体积过大会带来不少困扰,本文将使用Go语言编写一个图片批量压缩工具,文中的示例代码讲解详细,需要的可以了解下
在日常开发和办公中,图片体积过大会带来不少困扰:网页加载慢、存储占用大、邮件难以发送。很多时候,我们并不需要极致的画质,而是需要在清晰度和体积之间找到平衡。今天我们就用 Go 写一个图片批量压缩工具,从设计到实现,完整走一遍。
功能目标
- 批量处理:支持整个目录下的所有图片文件(支持递归)。
- 格式支持:JPEG、PNG、WebP。
- 自定义压缩质量:用户可以通过参数指定压缩比。
- 输出目录可选:压缩后的图片保存到指定文件夹,默认生成
output
。 - 保留文件结构:输出文件夹下的路径结构与原始一致。
- 简单易用:命令行参数运行,不依赖复杂环境。
技术选型
标准库:image
、image/jpeg
、image/png
第三方库:
github.com/chai2010/webp —— WebP 编解码
Go 并发:使用 goroutine + worker pool 来提升批量处理效率。
项目结构(示意)
img-compressor/
├── main.go
├── go.mod
完整代码(main.go)
package main import ( "fmt" "image" "image/jpeg" "image/png" "os" "path/filepath" "strings" "sync" "github.com/chai2010/webp" ) type Options struct { InputDir string OutputDir string Quality int Workers int Recursive bool } func main() { opts := Options{ InputDir: "./images", // 输入目录 OutputDir: "./output", // 输出目录 Quality: 75, // 压缩质量(0-100) Workers: 4, // 并发 worker 数 Recursive: true, // 是否递归 } if err := run(opts); err != nil { fmt.Println("❌ 发生错误:", err) os.Exit(1) } fmt.Println("✅ 批量压缩完成!") } func run(opts Options) error { // 收集所有待处理文件 var files []string err := filepath.Walk(opts.InputDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { if path != opts.InputDir && !opts.Recursive { return filepath.SkipDir } return nil } ext := strings.ToLower(filepath.Ext(info.Name())) if ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".webp" { files = append(files, path) } return nil }) if err != nil { return err } if len(files) == 0 { return fmt.Errorf("没有找到任何图片文件") } // worker pool fileCh := make(chan string) var wg sync.WaitGroup for i := 0; i < opts.Workers; i++ { wg.Add(1) go func() { defer wg.Done() for f := range fileCh { if err := compressImage(f, opts); err != nil { fmt.Printf("⚠️ 压缩失败 %s: %v\n", f, err) } else { fmt.Printf("✨ 压缩完成: %s\n", f) } } }() } for _, f := range files { fileCh <- f } close(fileCh) wg.Wait() return nil } // 压缩单张图片 func compressImage(path string, opts Options) error { inFile, err := os.Open(path) if err != nil { return err } defer inFile.Close() img, format, err := image.Decode(inFile) if err != nil { return fmt.Errorf("解码失败: %w", err) } // 输出路径 rel, _ := filepath.Rel(opts.InputDir, path) outPath := filepath.Join(opts.OutputDir, rel) if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil { return err } outFile, err := os.Create(outPath) if err != nil { return err } defer outFile.Close() switch format { case "jpeg": err = jpeg.Encode(outFile, img, &jpeg.Options{Quality: opts.Quality}) case "png": encoder := png.Encoder{CompressionLevel: png.BestCompression} err = encoder.Encode(outFile, img) case "webp": err = webp.Encode(outFile, img, &webp.Options{Quality: float32(opts.Quality)}) default: return fmt.Errorf("不支持的格式: %s", format) } return err }
使用方法
1.初始化项目并安装依赖:
go mod init img-compressor go get github.com/chai2010/webp
2.放置图片到 ./images
目录。
3.运行程序:
go run main.go
4.查看压缩结果: 所有压缩后的图片会保存在 ./output
目录下,目录结构保持不变。
实践要点与注意事项
- 质量参数:JPEG 和 WebP 可以用
0-100
来控制压缩比;PNG 主要通过压缩等级控制体积,但效果有限。 - 批量优化:若图片数量很多,可以用 goroutine worker pool 提升效率,避免一次性开太多协程。
- 格式兼容:WebP 在一些老旧系统和浏览器上兼容性不足,若是做网页资源,需要配合 fallback。
- 压缩策略:有时候先统一缩放图片(比如长边 1080px),再压缩比单纯调整质量更省空间。
进一步扩展
- 添加 命令行参数(例如用
flag
或cobra
),让用户可以指定输入目录、输出目录、质量、递归开关等。 - 支持 缩放功能(如最大宽高)。
- 输出 统计信息(压缩前后大小对比,总共节省空间)。
- 打包为跨平台可执行文件,方便非技术人员直接使用。
到此这篇关于Go语言开发实现一个图片批量压缩工具的文章就介绍到这了,更多相关Go图片批量压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!