-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.go
145 lines (133 loc) · 3.09 KB
/
common.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"bytes"
"errors"
"fmt"
"image"
"image/color"
"image/draw"
"image/png"
"io/ioutil"
"math"
"os"
"strings"
"github.com/corona10/goimagehash/transforms"
"github.com/nfnt/resize"
)
func decodeImage(filePath string) (image.Image, error) {
reader, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer reader.Close()
img, _, err := image.Decode(reader)
if err != nil {
return nil, err
}
return img, nil
}
func intRound(i int) int {
return int(math.Round(float64(i)))
}
func getAllParts(dirPath string) ([]string, error) {
res := []string{}
rd, err := ioutil.ReadDir(dirPath)
for _, fi := range rd {
if !fi.IsDir() {
res = append(res, dirPath+"/"+fi.Name())
}
}
return res, err
}
func getParentDirectory(dirctory string) string {
runes := []rune(dirctory)
l := strings.LastIndex(dirctory, "/")
if l > len(runes) {
l = len(runes)
} else if l == -1 {
return ""
}
return string(runes[0:l])
}
func readImage(filename string) (image.Image, int, int) {
img, _ := decodeImage(filename)
w := img.Bounds().Dx()
h := img.Bounds().Dy()
return img, w, h
}
func clipImage(img image.Image, x0, y0, x1, y1 int) (image.Image, error) {
switch img.(type) {
case *image.NRGBA:
img := img.(*image.NRGBA)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.NRGBA)
return subImg, nil
case *image.RGBA:
img := img.(*image.RGBA)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)
return subImg, nil
}
return nil, errors.New("not support image type")
}
func grayImage(m image.Image) *image.RGBA {
bounds := m.Bounds()
dx := bounds.Dx()
dy := bounds.Dy()
newRgba := image.NewRGBA(bounds)
for i := 0; i < dx; i++ {
for j := 0; j < dy; j++ {
_, g, _, a := m.At(i, j).RGBA()
gUint8 := uint8((g >> 8))
aUint8 := uint8(a >> 8)
newRgba.SetRGBA(i, j, color.RGBA{gUint8, gUint8, gUint8, aUint8})
}
}
return newRgba
}
func hammingDistance(lhash, rhash string) (int, error) {
if len(lhash) != len(rhash) {
return -1, errors.New("hash error")
}
n := 0
for i := 0; i < len(lhash); i++ {
if lhash[i] != rhash[i] {
n++
}
}
return n, nil
}
func differenceHash(img image.Image, size uint) (string, error) {
if img == nil {
return "", errors.New("Image object can not be nil")
}
resized := resize.Resize(size+1, size, img, resize.Bilinear)
var hash bytes.Buffer
pixels := transforms.Rgb2Gray(resized)
for i := 0; i < len(pixels); i++ {
for j := 0; j < len(pixels[i])-1; j++ {
if pixels[i][j] < pixels[i][j+1] {
hash.WriteByte('1')
} else {
hash.WriteByte('0')
}
}
}
return hash.String(), nil
}
func mergeImage(imgMatrix [][]*ImageMatrixData, output string, sWidth, sHeight, m, n int) error {
resImage := image.NewNRGBA(image.Rect(0, 0, sWidth, sHeight))
for x := 0; x < m; x++ {
for y := 0; y < n; y++ {
im := imgMatrix[x][y]
if im.Img != nil {
draw.Draw(resImage, resImage.Bounds(), im.Img, im.Img.Bounds().Min.Sub(image.Pt(im.X, im.Y)), draw.Over)
} else {
fmt.Println("orz")
}
}
}
out, err := os.Create(output)
if err != nil {
return err
}
return png.Encode(out, resImage)
}