forked from esimov/stackblur-go
/
main.go
executable file
·115 lines (102 loc) · 2.48 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"flag"
"fmt"
"image"
"image/color/palette"
"image/draw"
"image/gif"
"image/jpeg"
_ "image/jpeg"
"image/png"
_ "image/png"
"log"
"os"
"path"
"path/filepath"
"time"
"github.com/esimov/stackblur-go"
)
var (
source = flag.String("in", "", "Source")
destination = flag.String("out", "", "Destination")
radius = flag.Int("radius", 20, "Radius")
outputGif = flag.Bool("gif", false, "Output Gif")
)
func main() {
var imgs []image.Image
flag.Parse()
if len(*source) == 0 || len(*destination) == 0 {
log.Fatal("Usage: stackblur -in input.jpg -out out.jpg")
}
img, err := os.Open(*source)
defer img.Close()
src, _, err := image.Decode(img)
if err != nil {
panic(err)
}
start := time.Now()
if *outputGif {
for i := 1; i <= *radius; i++ {
img := stackblur.Process(src, uint32(i))
fmt.Printf("frame %d/%d\n", i, *radius)
go func() {
imgs = append(imgs, img)
if i == *radius {
if err := generateImage(*destination, img); err != nil {
log.Fatal(err)
}
}
}()
}
fmt.Printf("encoding GIF\n")
dest := path.Dir(*destination) + "/" + "output.gif"
if err := encodeGIF(imgs, dest); err != nil {
log.Fatal(err)
}
} else {
img := stackblur.Process(src, uint32(*radius))
if err := generateImage(*destination, img); err != nil {
log.Fatal(err)
}
}
end := time.Since(start)
fmt.Printf("\nGenerated in: %.2fs\n", end.Seconds())
}
// encodeGIF encodes the generated output into a gif file
func encodeGIF(imgs []image.Image, path string) error {
// load static image and construct outGif
outGif := &gif.GIF{}
for _, inPng := range imgs {
inGif := image.NewPaletted(inPng.Bounds(), palette.Plan9)
draw.Draw(inGif, inPng.Bounds(), inPng, image.Point{}, draw.Src)
outGif.Image = append(outGif.Image, inGif)
outGif.Delay = append(outGif.Delay, 0)
}
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
defer f.Close()
return gif.EncodeAll(f, outGif)
}
// generateImage generates the image type depending on the provided extension
func generateImage(dst string, img image.Image) error {
output, err := os.OpenFile(dst, os.O_CREATE|os.O_RDWR, 0755)
defer output.Close()
if err != nil {
return err
}
ext := filepath.Ext(output.Name())
switch ext {
case ".jpg", ".jpeg":
if err = jpeg.Encode(output, img, &jpeg.Options{Quality: 100}); err != nil {
return err
}
case ".png":
if err = png.Encode(output, img); err != nil {
return err
}
}
return nil
}