-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconvert.go
167 lines (138 loc) · 3.31 KB
/
convert.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
Package convert provides convert function
to some extension to other extension
*/
package convert
import (
"fmt"
"image"
"image/gif"
"image/jpeg"
"image/png"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
// Convert images with srcFmt in dir to images with dstFmt
func Convert(dir string, srcFmt string, dstFmt string) {
if !exists(dir) {
panic("ディレトリは存在しません")
}
fInfo, _ := os.Stat(dir)
if !fInfo.IsDir() {
panic("ディレクトリを指定してください")
}
files := dirwalk(dir, srcFmt, dstFmt)
for _, file := range files {
convertImage(file)
}
}
// find files with some extension in a directory recursively
func dirwalk(dir string, srcFmt string, dstFmt string) []FileInformation {
files, err := ioutil.ReadDir(dir)
if err != nil {
panic(err)
}
var paths []FileInformation
for _, file := range files {
if file.IsDir() {
paths = append(paths, dirwalk(filepath.Join(dir, file.Name()), srcFmt, dstFmt)...)
continue
}
name := file.Name()
pos := strings.LastIndex(name, ".") + 1
if name[pos:] != srcFmt {
continue
}
path := FileInformation{filepath.Join(dir, name[:pos-1]), srcFmt, dstFmt}
paths = append(paths, path)
}
return paths
}
// convert file with some extension to file with other extension
func convertImage(src FileInformation) {
if !isAvailableFormat(src.srcFmt) {
log.Fatal("指定した変換元の画像形式は無効です")
return
}
if !isAvailableFormat(src.dstFmt) {
log.Fatal("指定した変換先の画像形式は無効です")
return
}
startConvert(src)
}
// Encode the targer image
func startConvert(src FileInformation) {
file, err := os.Open(src.name + "." + src.srcFmt)
if err != nil {
log.Fatal(err)
return
}
defer file.Close()
img, _, err := decode(file)
if err != nil {
log.Fatal(err)
return
}
dstFile := makeDstFile(src)
out, err := os.Create(dstFile)
defer out.Close()
if !encode(src.dstFmt, out, img) {
log.Fatal("encodeに失敗")
}
}
// decode file
func decode(file *os.File) (image.Image, string, error) {
return image.Decode(file)
}
// encode image to dstFormat
func encode(format string, out *os.File, img image.Image) bool {
switch format {
case "jpeg", "jpg":
jpeg.Encode(out, img, nil)
return true
case "gif":
gif.Encode(out, img, nil)
return true
case "png":
png.Encode(out, img)
return true
default:
return false
}
}
// make destination file
func makeDstFile(src FileInformation) string {
dstDir := "output"
if _, err := os.Stat(dstDir); os.IsNotExist(err) {
os.Mkdir(dstDir, 0777)
}
return dstDir + "/" + fmt.Sprintf("%s.%s", getFileNameWithoutExt(src.name), src.dstFmt)
}
// check if this format is avalable
func isAvailableFormat(format string) bool {
lowerFormat := strings.ToLower(format)
switch lowerFormat {
case "jpg", "jpeg", "png", "gif":
return true
default:
return false
}
}
// Get file name withour extension
func getFileNameWithoutExt(path string) string {
return filepath.Base(path[:len(path)-len(filepath.Ext(path))])
}
// Check if file exists
func exists(filename string) bool {
_, err := os.Stat(filename)
return err == nil
}
// FileInformation contains Name and srcFmt and dstFmt.
type FileInformation struct {
name string // name of a file
srcFmt string // original format of a file
dstFmt string // format to convert
}