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