/
main.go
92 lines (83 loc) · 2 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"flag"
"image"
"image/color"
"image/draw"
"image/gif"
_ "image/jpeg"
_ "image/png"
"log"
"math"
"os"
"github.com/BurntSushi/graphics-go/graphics"
"github.com/BurntSushi/graphics-go/graphics/interp"
"github.com/lucasb-eyer/go-colorful"
"github.com/soniakeys/quant/median"
)
var (
delay = flag.Int("d", 10, "delay")
output = flag.String("o", "animated.gif", "output filename")
reverse = flag.Bool("r", false, "inverse rotation")
speed = flag.Float64("x", 1.0, "rotating speed")
zoom = flag.Bool("z", false, "zoom animation") // experimental
bg = flag.String("bg", "#FFFFFF", "background color")
)
func main() {
flag.Parse()
c, err := colorful.Hex(*bg)
if err != nil {
log.Fatal(err)
}
f, err := os.Open(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
src, _, err := image.Decode(f)
if err != nil {
log.Fatal(err)
}
f.Close()
g := &gif.GIF{
Image: []*image.Paletted{},
Delay: []int{},
LoopCount: 0,
}
var base float64 = (math.Pi * 2) * 10 * (*speed) / 360
if *reverse {
base *= -1
}
limit := int(360 / 10 / (*speed))
q := median.Quantizer(256)
p := q.Quantize(make(color.Palette, 0, 256), src)
for i := 0; i < limit; i++ {
dst := image.NewPaletted(src.Bounds(), p)
draw.Draw(dst, src.Bounds(), &image.Uniform{c}, image.ZP, draw.Src)
err = graphics.Rotate(dst, src, &graphics.RotateOptions{Angle: base * float64(i)})
if err != nil {
log.Fatal(err)
}
if *zoom {
w, h := float64(src.Bounds().Dx()), float64(src.Bounds().Dy())
tmp := image.NewPaletted(src.Bounds(), p)
draw.Draw(tmp, src.Bounds(), &image.Uniform{c}, image.ZP, draw.Src)
z := float64(0.5 + float64(i)/30.0)
graphics.I.
Scale(z, z).
Translate((w-w*z)/2, (h-h*z)/2).
Transform(tmp, dst, interp.Bilinear)
dst = tmp
}
g.Image = append(g.Image, dst)
g.Delay = append(g.Delay, *delay)
}
out, err := os.Create(*output)
if err != nil {
log.Fatal(err)
}
defer out.Close()
err = gif.EncodeAll(out, g)
if err != nil {
log.Fatal(err)
}
}