/
imgutil.go
107 lines (96 loc) · 2.55 KB
/
imgutil.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Package imgutil implements some image utility functions.
package imgutil
import (
"image"
"image/color"
_ "image/gif" // support for decoding gif images.
"image/jpeg"
"image/png"
"os"
"golang.org/x/image/bmp"
)
// ReadFile reads an image file (gif, jpeg or png) specified by imgPath and
// returns it as an image.Image.
func ReadFile(imgPath string) (img image.Image, err error) {
fr, err := os.Open(imgPath)
if err != nil {
return nil, err
}
defer fr.Close()
img, _, err = image.Decode(fr)
if err != nil {
return nil, err
}
return img, nil
}
// WriteFile writes the image data to a PNG file specified by imgPath. WriteFile
// creates the named file using mode 0666 (before umask), truncating it if it
// already exists.
func WriteFile(imgPath string, img image.Image) (err error) {
fw, err := os.Create(imgPath)
if err != nil {
return err
}
defer fw.Close()
if err := png.Encode(fw, img); err != nil {
return err
}
return nil
}
// WriteJPEG writes the image data to a JPEG file specified by imgPath.
// writeJPEG creates the named file using mode 0666 (before umask), truncating
// it if it already exists. The quality of the output image is within the range
// [1, 100]; higher is better.
func WriteJPEG(imgPath string, img image.Image, quality int) (err error) {
fw, err := os.Create(imgPath)
if err != nil {
return err
}
defer fw.Close()
options := &jpeg.Options{Quality: quality}
if err := jpeg.Encode(fw, img, options); err != nil {
return err
}
return nil
}
// WriteBMP writes the image data to a BMP file specified by imgPath.
// WriteBMP creates the named file using mode 0666 (before umask), truncating
// it if it already exists
func WriteBMP(imgPath string, img image.Image) (err error) {
fw, err := os.Create(imgPath)
if err != nil {
return err
}
defer fw.Close()
if err := bmp.Encode(fw, img); err != nil {
return err
}
return nil
}
// Equal returns true if the images img1 and img2 are equal, and false
// otherwise.
func Equal(img1, img2 image.Image) bool {
rect1 := img1.Bounds()
rect2 := img2.Bounds()
// Compare bounds.
if rect1 != rect2 {
return false
}
// Compare pixel colors.
for x := rect1.Min.X; x < rect1.Max.X; x++ {
for y := rect1.Min.Y; y < rect1.Max.Y; y++ {
c1 := img1.At(x, y)
c2 := img2.At(x, y)
if !ColorEq(c1, c2) {
return false
}
}
}
return true
}
// ColorEq returns true if the colors c1 and c2 are equal, and false otherwise.
func ColorEq(c1, c2 color.Color) bool {
r1, g1, b1, a1 := c1.RGBA()
r2, g2, b2, a2 := c2.RGBA()
return r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2
}