Mercurial > mercurial > hgweb_golang.cgi
view src/IMGmanip.go @ 0:de451fa0c9cd
golang repository.
author | pyon@macmini |
---|---|
date | Sat, 01 Oct 2016 11:16:31 +0900 |
parents | |
children | 9072560fc0f2 |
line wrap: on
line source
/* Image Manipulator - ver 0.2 ( Last Change: 2016-08-21 Sun 09:51:52.) */ package main import( "errors" "flag" "fmt" "image" "image/jpeg" "image/png" "io" "os" "strings" "strconv" ) func main() { ver := "0.2" // arguments kind := flag.String( "t", "", "file type : jpeg / png" ) resize := flag.String( "s", "", "new size : 600x800 / 320x0 / ..." ) crop := flag.String( "c", "", "crop size : 300x200+10+35" ) angle := flag.Uint( "r", 0, "rotate : 90 / 180 / 270" ) flag.Parse() if flag.NFlag() == 0 { fmt.Fprintf( os.Stderr, "\n=== Image-Manipulator - version %s ===", ver ) fmt.Fprintf( os.Stderr, "\n$ imgmanip [option parameter] < infile > outfile\n" ) flag.PrintDefaults() os.Exit( 1 ) } // convert if *kind != "" { err := Convert( os.Stdin, os.Stdout, *kind ); if err != nil { fmt.Fprintf( os.Stderr, "%s: %v\n", *kind, err ) os.Exit( 1 ) } return } // resize if *resize != "" { err := Resize( os.Stdin, os.Stdout, *resize ); if err != nil { fmt.Fprintf( os.Stderr, "resize: %v\n", err ) os.Exit( 1 ) } return } // crop if *crop != "" { err := Crop( os.Stdin, os.Stdout, *crop ); if err != nil { fmt.Fprintf( os.Stderr, "crop: %v\n", err ) os.Exit( 1 ) } return } // rotate if *angle != 0 { err := Rotate( os.Stdin, os.Stdout, *angle ); if err != nil { fmt.Fprintf( os.Stderr, "rotate: %v\n", err ) os.Exit( 1 ) } return } } func Convert( in io.Reader, out io.Writer, kind string ) error { img, _, err := image.Decode( in ); if err != nil { return err } switch kind { case "jpeg": return jpeg.Encode( out, img, &jpeg.Options{ Quality: 100 } ) case "png": return png.Encode( out, img ) } return errors.New( "image-type is not supported") } func Resize( in io.Reader, out io.Writer, size string ) error { img, kind, err := image.Decode( in ); if err != nil { return err } srcW := img.Bounds().Max.X srcH := img.Bounds().Max.Y wh := strings.Split( size, "x" ) w, err := strconv.Atoi( wh[0] ); if err != nil || w < 0 { return errors.New( "invalid width" ) } h, err := strconv.Atoi( wh[1] ); if err != nil || h < 0 { return errors.New( "invalid height" ) } if w == 0 && h == 0 { return errors.New( "invalid size" ) } if w == 0 { w = h * srcW / srcH } if h == 0 { h = w * srcH / srcW } dst := image.NewNRGBA( image.Rect( 0, 0, w, h ) ) for x := 0; x < w; x++ { for y := 0; y < h; y++ { dst.Set( x, y, img.At( x * srcW / w, y * srcH / h ) ) } } switch kind { case "jpeg": return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) case "png": return png.Encode( out, dst ) } return errors.New( "image-type is not supported") } func Crop( in io.Reader, out io.Writer, geo string ) error { img, kind, err := image.Decode( in ); if err != nil { return err } srcW := img.Bounds().Max.X srcH := img.Bounds().Max.Y buf := strings.Split( geo, "x" ) w, err := strconv.Atoi( buf[0] ); if err != nil || w < 0 || w > srcW { return errors.New( "invalid width" ) } buf = strings.Split( buf[1], "+" ) h, err := strconv.Atoi( buf[0] ); if err != nil || h < 0 || h > srcH { return errors.New( "invalid height" ) } x0, err := strconv.Atoi( buf[1] ); if err != nil || x0 < 0 { return errors.New( "invalid x" ) } y0, err := strconv.Atoi( buf[2] ); if err != nil || y0 < 0 { return errors.New( "invalid y" ) } var dst *image.NRGBA dst = image.NewNRGBA( image.Rect( 0, 0, w, h ) ) for x := 0; x < x0 + w; x++ { for y := 0; y < y0 + h; y++ { dst.Set( x, y, img.At( x0 + x, y0 + y ) ) } } switch kind { case "jpeg": return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) case "png": return png.Encode( out, dst ) } return errors.New( "image-type is not supported") } func Rotate( in io.Reader, out io.Writer, angle uint ) error { img, kind, err := image.Decode( in ); if err != nil { return err } srcW := img.Bounds().Max.X srcH := img.Bounds().Max.Y var dst *image.NRGBA switch angle { case 90: dst = image.NewNRGBA( image.Rect( 0, 0, srcH, srcW ) ) for x := 0; x < srcH; x++ { for y := 0; y < srcW; y++ { dst.Set( x, y, img.At( y, srcH - x ) ) } } case 180: dst = image.NewNRGBA( image.Rect( 0, 0, srcW, srcH ) ) for x := 0; x < srcW; x++ { for y := 0; y < srcH; y++ { dst.Set( x, y, img.At( srcW - x, srcH - y ) ) } } case 270: dst = image.NewNRGBA( image.Rect( 0, 0, srcH, srcW ) ) for x := 0; x < srcH; x++ { for y := 0; y < srcW; y++ { dst.Set( x, y, img.At( y, x ) ) } } default: return errors.New( "bad angle" ) } switch kind { case "jpeg": return jpeg.Encode( out, dst, &jpeg.Options{ Quality: 100 } ) case "png": return png.Encode( out, dst ) } return errors.New( "image-type is not supported") }