1/* 2 * Copyright (c) 2014 Christian Muehlhaeuser 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a copy 5 * of this software and associated documentation files (the "Software"), to deal 6 * in the Software without restriction, including without limitation the rights 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 * copies of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in all 12 * copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Authors: 23 * Christian Muehlhaeuser <muesli@gmail.com> 24 * Michael Wendland <michael@michiwend.com> 25 * Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> 26 */ 27 28/* 29Package smartcrop implements a content aware image cropping library based on 30Jonas Wagner's smartcrop.js https://github.com/jwagner/smartcrop.js 31*/ 32package smartcrop 33 34import ( 35 "errors" 36 "image" 37 "image/color" 38 "image/jpeg" 39 "image/png" 40 "os" 41 "path/filepath" 42) 43 44func debugOutput(debug bool, img *image.RGBA, debugType string) { 45 if debug { 46 writeImage("png", img, "./smartcrop_"+debugType+".png") 47 } 48} 49 50func writeImage(imgtype string, img image.Image, name string) error { 51 if err := os.MkdirAll(filepath.Dir(name), 0755); err != nil { 52 panic(err) 53 } 54 55 switch imgtype { 56 case "png": 57 return writeImageToPng(img, name) 58 case "jpeg": 59 return writeImageToJpeg(img, name) 60 } 61 62 return errors.New("Unknown image type") 63} 64 65func writeImageToJpeg(img image.Image, name string) error { 66 fso, err := os.Create(name) 67 if err != nil { 68 return err 69 } 70 defer fso.Close() 71 72 return jpeg.Encode(fso, img, &jpeg.Options{Quality: 100}) 73} 74 75func writeImageToPng(img image.Image, name string) error { 76 fso, err := os.Create(name) 77 if err != nil { 78 return err 79 } 80 defer fso.Close() 81 82 return png.Encode(fso, img) 83} 84 85func drawDebugCrop(topCrop Crop, o *image.RGBA) { 86 width := o.Bounds().Dx() 87 height := o.Bounds().Dy() 88 89 for y := 0; y < height; y++ { 90 for x := 0; x < width; x++ { 91 r, g, b, _ := o.At(x, y).RGBA() 92 r8 := float64(r >> 8) 93 g8 := float64(g >> 8) 94 b8 := uint8(b >> 8) 95 96 imp := importance(topCrop, x, y) 97 98 if imp > 0 { 99 g8 += imp * 32 100 } else if imp < 0 { 101 r8 += imp * -64 102 } 103 104 nc := color.RGBA{uint8(bounds(r8)), uint8(bounds(g8)), b8, 255} 105 o.SetRGBA(x, y, nc) 106 } 107 } 108} 109