使用Goroutine和channel实现并发图片处理,通过worker池读取任务并处理,结合image包和resize库完成缩放等操作,利用WaitGroup等待所有任务结束,并控制并发数防止资源耗尽。

在Go语言中实现并发图片处理,关键是利用Goroutine和通道(channel)高效调度多个图片任务。通过并发执行,可以显著提升批量图片处理的速度,比如缩放、裁剪、格式转换等操作。
使用Goroutine并发处理多张图片
将每张图片的处理任务交给独立的Goroutine执行,主线程通过channel接收完成状态或结果,避免阻塞。
示例思路:
- 创建一个任务channel,输入待处理的图片路径
- 启动固定数量的worker Goroutine从channel读取任务并处理
- 使用WaitGroup等待所有任务完成
代码片段:
立即学习“go语言免费学习笔记(深入)”;
func processImages(imagePaths []string, workerCount int) {
var wg sync.WaitGroup
taskCh := make(chan string)
// 启动worker
for i := 0; i < workerCount; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for path := range taskCh {
err := processSingleImage(path)
if err != nil {
log.Printf("处理失败 %s: %v", path, err)
}
}
}()
}
// 发送任务
for _, path := range imagePaths {
taskCh <- path
}
close(taskCh)
wg.Wait()}
结合image包进行实际图片操作
Golang内置的image、image/jpeg、image/png等包支持图片解码与编码。可配合第三方库如github.com/nfnt/resize进行缩放。
常见步骤:
- 读取图片文件并解码为image.Image对象
- 使用resize.Resize调整尺寸
- 将处理后的图像编码保存为新文件
处理函数示例:
import (
"image"
"image/jpeg"
"os"
"github.com/nfnt/resize"
)
func processSingleImage(path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
img, format, err := image.Decode(file)
if err != nil {
return err
}
// 缩放至800x600
resized := resize.Resize(800, 600, img, resize.Lanczos3)
out, _ := os.Create("processed_" + filepath.Base(path))
defer out.Close()
switch format {
case "jpeg", "jpg":
return jpeg.Encode(out, resized, nil)
case "png":
return png.Encode(out, resized)
default:
return fmt.Errorf("不支持的格式: %s", format)
}}
控制并发数量避免资源耗尽
开启过多Goroutine可能导致内存暴涨或系统句柄不足。建议限制worker数量,例如根据CPU核心数设置workerCount为4~16。
也可以使用带缓冲的channel作为信号量控制并发:
semaphore := make(chan struct{}, 5) // 最多5个并发
for _, path := range imagePaths {
semaphore <- struct{}{}
go func(p string) {
defer func() { <-semaphore }()
processSingleImage(p)
}(path)
}
基本上就这些。合理利用Goroutine、channel和第三方图像库,就能写出高效稳定的并发图片处理器。关键是控制好并发度,避免系统过载。










