Mercurial > mercurial > hgweb_golang.cgi
comparison src/IMGmanip.go @ 0:de451fa0c9cd
golang repository.
author | pyon@macmini |
---|---|
date | Sat, 01 Oct 2016 11:16:31 +0900 |
parents | |
children | 9072560fc0f2 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:de451fa0c9cd |
---|---|
1 /* Image Manipulator - ver 0.2 ( Last Change: 2016-08-21 Sun 09:51:52.) */ | |
2 package main | |
3 | |
4 import( | |
5 "errors" | |
6 "flag" | |
7 "fmt" | |
8 "image" | |
9 "image/jpeg" | |
10 "image/png" | |
11 "io" | |
12 "os" | |
13 "strings" | |
14 "strconv" | |
15 ) | |
16 | |
17 func main() { | |
18 ver := "0.2" | |
19 | |
20 // arguments | |
21 kind := flag.String( "t", "", "file type : jpeg / png" ) | |
22 resize := flag.String( "s", "", "new size : 600x800 / 320x0 / ..." ) | |
23 crop := flag.String( "c", "", "crop size : 300x200+10+35" ) | |
24 angle := flag.Uint( "r", 0, "rotate : 90 / 180 / 270" ) | |
25 | |
26 flag.Parse() | |
27 if flag.NFlag() == 0 { | |
28 fmt.Fprintf( os.Stderr, "\n=== Image-Manipulator - version %s ===", ver ) | |
29 fmt.Fprintf( os.Stderr, "\n$ imgmanip [option parameter] < infile > outfile\n" ) | |
30 flag.PrintDefaults() | |
31 os.Exit( 1 ) | |
32 } | |
33 | |
34 // convert | |
35 if *kind != "" { | |
36 err := Convert( os.Stdin, os.Stdout, *kind ); if err != nil { | |
37 fmt.Fprintf( os.Stderr, "%s: %v\n", *kind, err ) | |
38 os.Exit( 1 ) | |
39 } | |
40 return | |
41 } | |
42 | |
43 // resize | |
44 if *resize != "" { | |
45 err := Resize( os.Stdin, os.Stdout, *resize ); if err != nil { | |
46 fmt.Fprintf( os.Stderr, "resize: %v\n", err ) | |
47 os.Exit( 1 ) | |
48 } | |
49 return | |
50 } | |
51 | |
52 // crop | |
53 if *crop != "" { | |
54 err := Crop( os.Stdin, os.Stdout, *crop ); if err != nil { | |
55 fmt.Fprintf( os.Stderr, "crop: %v\n", err ) | |
56 os.Exit( 1 ) | |
57 } | |
58 return | |
59 } | |
60 | |
61 // rotate | |
62 if *angle != 0 { | |
63 err := Rotate( os.Stdin, os.Stdout, *angle ); if err != nil { | |
64 fmt.Fprintf( os.Stderr, "rotate: %v\n", err ) | |
65 os.Exit( 1 ) | |
66 } | |
67 return | |
68 } | |
69 } | |
70 | |
71 func Convert( in io.Reader, out io.Writer, kind string ) error { | |
72 | |
73 img, _, err := image.Decode( in ); if err != nil { | |
74 return err | |
75 } | |
76 | |
77 switch kind { | |
78 case "jpeg": | |
79 return jpeg.Encode( out, img, &jpeg.Options{ Quality: 100 } ) | |
80 case "png": | |
81 return png.Encode( out, img ) | |
82 } | |
83 | |
84 return errors.New( "image-type is not supported") | |
85 } | |
86 | |
87 func Resize( in io.Reader, out io.Writer, size string ) error { | |
88 | |
89 img, kind, err := image.Decode( in ); if err != nil { | |
90 return err | |
91 } | |
92 srcW := img.Bounds().Max.X | |
93 srcH := img.Bounds().Max.Y | |
94 | |
95 wh := strings.Split( size, "x" ) | |
96 w, err := strconv.Atoi( wh[0] ); if err != nil || w < 0 { | |
97 return errors.New( "invalid width" ) | |
98 } | |
99 h, err := strconv.Atoi( wh[1] ); if err != nil || h < 0 { | |
100 return errors.New( "invalid height" ) | |
101 } | |
102 if w == 0 && h == 0 { | |
103 return errors.New( "invalid size" ) | |
104 } | |
105 if w == 0 { | |
106 w = h * srcW / srcH | |
107 } | |
108 if h == 0 { | |
109 h = w * srcH / srcW | |
110 } | |
111 | |
112 dst := image.NewNRGBA( image.Rect( 0, 0, w, h ) ) | |
113 for x := 0; x < w; x++ { | |
114 for y := 0; y < h; y++ { | |
115 dst.Set( x, y, img.At( x * srcW / w, y * srcH / h ) ) | |
116 } | |
117 } | |
118 | |
119 switch kind { | |
120 case "jpeg": | |
121 return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) | |
122 case "png": | |
123 return png.Encode( out, dst ) | |
124 } | |
125 | |
126 return errors.New( "image-type is not supported") | |
127 } | |
128 | |
129 func Crop( in io.Reader, out io.Writer, geo string ) error { | |
130 | |
131 img, kind, err := image.Decode( in ); if err != nil { | |
132 return err | |
133 } | |
134 srcW := img.Bounds().Max.X | |
135 srcH := img.Bounds().Max.Y | |
136 | |
137 buf := strings.Split( geo, "x" ) | |
138 w, err := strconv.Atoi( buf[0] ); if err != nil || w < 0 || w > srcW { | |
139 return errors.New( "invalid width" ) | |
140 } | |
141 buf = strings.Split( buf[1], "+" ) | |
142 h, err := strconv.Atoi( buf[0] ); if err != nil || h < 0 || h > srcH { | |
143 return errors.New( "invalid height" ) | |
144 } | |
145 x0, err := strconv.Atoi( buf[1] ); if err != nil || x0 < 0 { | |
146 return errors.New( "invalid x" ) | |
147 } | |
148 y0, err := strconv.Atoi( buf[2] ); if err != nil || y0 < 0 { | |
149 return errors.New( "invalid y" ) | |
150 } | |
151 | |
152 var dst *image.NRGBA | |
153 | |
154 dst = image.NewNRGBA( image.Rect( 0, 0, w, h ) ) | |
155 for x := 0; x < x0 + w; x++ { | |
156 for y := 0; y < y0 + h; y++ { | |
157 dst.Set( x, y, img.At( x0 + x, y0 + y ) ) | |
158 } | |
159 } | |
160 | |
161 switch kind { | |
162 case "jpeg": | |
163 return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) | |
164 case "png": | |
165 return png.Encode( out, dst ) | |
166 } | |
167 | |
168 return errors.New( "image-type is not supported") | |
169 } | |
170 | |
171 func Rotate( in io.Reader, out io.Writer, angle uint ) error { | |
172 | |
173 img, kind, err := image.Decode( in ); if err != nil { | |
174 return err | |
175 } | |
176 srcW := img.Bounds().Max.X | |
177 srcH := img.Bounds().Max.Y | |
178 | |
179 var dst *image.NRGBA | |
180 switch angle { | |
181 case 90: | |
182 dst = image.NewNRGBA( image.Rect( 0, 0, srcH, srcW ) ) | |
183 for x := 0; x < srcH; x++ { | |
184 for y := 0; y < srcW; y++ { | |
185 dst.Set( x, y, img.At( y, srcH - x ) ) | |
186 } | |
187 } | |
188 case 180: | |
189 dst = image.NewNRGBA( image.Rect( 0, 0, srcW, srcH ) ) | |
190 for x := 0; x < srcW; x++ { | |
191 for y := 0; y < srcH; y++ { | |
192 dst.Set( x, y, img.At( srcW - x, srcH - y ) ) | |
193 } | |
194 } | |
195 case 270: | |
196 dst = image.NewNRGBA( image.Rect( 0, 0, srcH, srcW ) ) | |
197 for x := 0; x < srcH; x++ { | |
198 for y := 0; y < srcW; y++ { | |
199 dst.Set( x, y, img.At( y, x ) ) | |
200 } | |
201 } | |
202 default: | |
203 return errors.New( "bad angle" ) | |
204 } | |
205 | |
206 switch kind { | |
207 case "jpeg": | |
208 return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) | |
209 case "png": | |
210 return png.Encode( out, dst ) | |
211 } | |
212 | |
213 return errors.New( "image-type is not supported") | |
214 } | |
215 |