使用Golang将多张图片合并为GIF动态图
发表时间: 2024-01-26 22:29
在Go语言实际开发中,会遇到将几张图片合成gif动态图情况,这里整理了两种实现方式
使用第三方库有
https://github.com/disintegration/imaging
支持图片格式 ".jpg",".jpeg",".gif",".png",".bmp",".webp"
package mainimport ( "errors" "fmt" "github.com/disintegration/imaging" "golang.org/x/image/webp" "image/draw" "image" "image/color/palette" "image/gif" "os" "path/filepath")func main() { imgArr := []string{"./img/1.jpeg","./img/2.png","./img/3.jpg","./img/4.jpg","./img/5.gif","./img/7.bmp"} delay:=100//设置延迟 //新建gif结构体 outGif := &gif.GIF{} for _, img := range imgArr { //图像解码 inGif, err:=imageDecode(img) //如果是 jpg jpeg gif bmp png 类型,可替换imageDecode //inGif, err:=imaging.Open(img) if err!=nil { fmt.Println("图像解码失败",err) continue } //修改图片大小 inGif=imaging.Resize(inGif,500,500,imaging.Lanczos) bounds := inGif.Bounds() //创建一个新的image.Paletted对象用于存储带有调色板的图像 palettedImg := image.NewPaletted(bounds, palette.Plan9) //将原始图像绘制到 palettedImg draw.Draw(palettedImg, bounds, inGif, bounds.Min, draw.Src) outGif.Image = append(outGif.Image, palettedImg) outGif.Delay = append(outGif.Delay, delay) } f, _ := os.OpenFile("output.gif", os.O_WRONLY|os.O_CREATE, 0600) defer f.Close() gif.EncodeAll(f, outGif)}//图像解码func imageDecode(file string) (image.Image,error) { f, err := os.Open(file) if err!=nil { return nil, err } defer f.Close() ext:=filepath.Ext(file) switch ext { case ".jpg",".jpeg",".gif",".png",".bmp": return imaging.Decode(f) case ".webp": return webp.Decode(f) default: return nil,errors.New("图片格式错误") }}
不通过第三方库 支持图片格式 ".jpg",".jpeg",".gif",".png",".bmp",".webp"
package mainimport ( "errors" "fmt" "golang.org/x/image/bmp" "golang.org/x/image/draw" "golang.org/x/image/webp" "image" "image/color/palette" "image/gif" "image/jpeg" "image/png" "os" "path/filepath")func main() { imgArr := []string{"./img/1.jpeg","./img/2.png","./img/3.jpg","./img/4.jpg","./img/5.gif","./img/7.bmp"} delay:=100//设置延迟 //新建gif结构体 outGif := &gif.GIF{} for _, img := range imgArr { //图像解码 inGif,err:=imageDecode(img) if err!=nil { fmt.Println("图像解码失败",err) continue } //缩放 dst := image.NewRGBA(image.Rect(0, 0, 640, 640)) resize(dst,inGif) bounds := dst.Bounds() //创建一个新的image.Paletted对象用于存储带有调色板的图像 palettedImg := image.NewPaletted(bounds, palette.Plan9) //将原始图像绘制到 palettedImg draw.Draw(palettedImg, bounds, dst, bounds.Min, draw.Src) outGif.Image = append(outGif.Image, palettedImg) outGif.Delay = append(outGif.Delay, delay) } f, _ := os.OpenFile("output.gif", os.O_WRONLY|os.O_CREATE, 0600) defer f.Close() gif.EncodeAll(f, outGif)}//图像解码func imageDecode(file string) (image.Image,error) { f, err := os.Open(file) if err!=nil { return nil, err } defer f.Close() ext:=filepath.Ext(file) switch ext { case ".jpg",".jpeg": return jpeg.Decode(f) case ".png": return png.Decode(f) case ".bmp": return bmp.Decode(f) case ".gif": return gif.Decode(f) case ".webp": return webp.Decode(f) default: return nil,errors.New("图片格式错误") }}//不等比例缩放到指定大小,func resize(dst *image.RGBA, src image.Image) error { sw, sh := src.Bounds().Dx(), src.Bounds().Dy() dw, dh := dst.Bounds().Dx(), dst.Bounds().Dy() scaleW, scaleH := float64(sw)/float64(dw), float64(sh)/float64(dh) for y := 0; y < dh; y++ { for x := 0; x < dw; x++ { dst.Set(x, y, src.At(int(float64(x)*scaleW), int(float64(y)*scaleH))) } } return nil}