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 |
