-
Notifications
You must be signed in to change notification settings - Fork 0
/
image-basic.go
87 lines (71 loc) · 2.53 KB
/
image-basic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package mediaprocessor
import (
"fmt"
"image"
"image/jpeg"
"log"
"math"
"os"
"github.com/disintegration/imaging"
)
// ImageBasic is an ImageProcessor which uses a mix of Go image generation libraries
type ImageBasic struct{}
// ProcessImage processes a single image
func (i *ImageBasic) Resize(m *MediaJob) (filenames []string, err error) {
// TODO: Do a better job of handling errors - returning early and using multierror to report all errors to the caller
// Read file in
// os.File conforms to io.Reader, which we can call Decode on
fh, err := os.Open(m.InputFile.Path)
defer fh.Close()
if err != nil {
log.Fatal("Could not read file")
}
srcImage, _, err := image.Decode(fh)
if err != nil {
log.Fatal("Error decoding image: ", m.InputFile.Path)
}
for _, imageConfig := range m.MediaConfig.ImageConfigurations {
// Resize image
resizedImage := resizeImage(srcImage, imageConfig.MaxWidth)
// Write file out
outputFilepath := m.OutputPath(imageConfig)
fmt.Println("File output path is", outputFilepath)
outfh, err := os.Create(outputFilepath)
defer outfh.Close()
if err != nil {
log.Fatal(err)
}
switch imageConfig.FileType {
case JPG:
fmt.Println("Encoding output file to JPG")
jpeg.Encode(outfh, resizedImage, &jpeg.Options{Quality: imageConfig.Quality})
case WebP:
fmt.Println("WebP output disabled")
// fmt.Println("Encoding output file to WebP with chai2010")
// var buf bytes.Buffer
// if err = webp.Encode(&buf, resizedImage, &webp.Options{Quality: float32(imageConfig.Quality)}); err != nil {
// log.Println(err)
// }
// if err = ioutil.WriteFile(outputFilepath, buf.Bytes(), 0664); err != nil {
// log.Println(err)
// }
default:
fmt.Println("Error: unknown output format:", imageConfig.FileType)
continue
}
filenames = append(filenames, outputFilepath)
}
return
}
// imaging library typically returns image.NRGBA, so let's roll with that for now
func resizeImage(srcImage image.Image, targetWidth int) (resizedImage *image.NRGBA) {
imgWidth := srcImage.Bounds().Max.X
imgHeight := srcImage.Bounds().Max.Y
aspectRatio := float64(imgHeight) / float64(imgWidth)
resizeWidth := int(math.Min(float64(imgWidth), float64(targetWidth)))
resizeHeight := int(float64(resizeWidth) * aspectRatio)
// fmt.Printf("Resizing %d x %d -> %d x %d\n", imgWidth, imgHeight, resizeWidth, resizeHeight)
// TODO: select best resizing algorithm. Lanczos sounds like a good starting point.
resizedImage = imaging.Resize(srcImage, resizeWidth, resizeHeight, imaging.Lanczos)
return
}