image/gif 包的用法总结
要制作一个gif动画文件总共分两步
第一步 创建gif结构体实例,设置相关属性
type GIF struct {
Image []*image.Paletted // 将每一帧的image实例放入这个数组
Delay []int // 将每一帧对应的延时时间放入这个数组
LoopCount int // gif动画循环的次数
Disposal []byte
Config image.Config
BackgroundIndex byte
}
第二步 编码输出到指定文件
gif.EncodeAll(file, &animated)
完成创建过程如下
gif.EncodeAll(file, &gif.GIF{
Image: pics,
Delay: delay,
LoopCount: 5 * len(delay),
})
** 实战1 制作利萨如老电影特效动画**
代码如下
package main
import (
"image"
"math"
"image/color"
"image/gif"
"io"
"math/rand"
"os"
)
var palette = []color.Color{color.White, color.Black}
const (
whiteIndex = 0
blackIndex = 1
)
func main() {
file, _ := os.Create("math.gif")
lissajous(file)
}
func lissajous(out io.Writer) {
const (
cycles = 5 //
res = 0.001
size = 100
nframes = 64 // 设置gif的帧数
delay = 8
)
freq := rand.Float64() * 3.0 //
// 创建gif动画数组
anim := gif.GIF{LoopCount: nframes}
//
phase := 0.0
for i := 0; i < nframes; i++ {
rect := image.Rect(0, 0, 2*size+1, 2*size+1)
img := image.NewPaletted(rect, palette)
for t := 0.0; t < cycles*2*math.Pi; t += res {
x := math.Sin(t)
y := math.Sin(t*freq + phase)
// 给图片指定的位置填充颜色
img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex)
}
phase += 0.1
// 设置每一帧的延时
anim.Delay = append(anim.Delay, delay)
// 设置每一帧的图片
anim.Image = append(anim.Image, img)
}
// 将编码后的gif动画文件 保存至指定的文件中
gif.EncodeAll(out, &anim)
}
实战2 将多张照片拼接成gif图片
package main
import (
"fmt"
"path"
"image"
"image/color/palette"
"image/draw"
"image/gif"
"io/ioutil"
"log"
"os"
)
func main() {
generateGif("./images", "./images/out.gif")
}
// src 图片所在的数组
func generateGif(srcPath string, savaPath string) {
const (
delay = 100 // 100 表示1秒
loopCount = 1
)
// 检查路径是否存在
// 读取路径中的图片文件
files, err := ioutil.ReadDir(srcPath)
if err != nil {
log.Fatal(err)
}
anim := gif.GIF{}
for _, file := range files {
imgPath := srcPath + "/" + file.Name()
if path.Ext(imgPath) != ".jpg" {
continue
}
fmt.Println(imgPath)
f, _ := os.Open(imgPath)
// 对图片进行编码
img, _, err := image.Decode(f)
if err != nil {
fmt.Println(err)
}
// 创建调色板
imgPalatte := image.NewPaletted(image.Rect(0, 0, 1000, 1000), palette.Plan9)
draw.FloydSteinberg.Draw(imgPalatte, img.Bounds(), img, image.ZP)
anim.Image = append(anim.Image, imgPalatte)
anim.Delay = append(anim.Delay, delay)
}
out, _ := os.Create(savaPath)
gif.EncodeAll(out, &anim)
}