-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash.go
66 lines (59 loc) · 1.75 KB
/
hash.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
package seenit
import (
"fmt"
"golang.org/x/image/draw"
_ "golang.org/x/image/webp"
"image"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
)
const (
seenMarker = "seen"
)
func HaveSeen(community string, hash string, db Database) (bool, error) {
bucket, err := db.GetBucket(community)
if err != nil {
return false, err
}
return bucket.Has(hash)
}
func RecordHash(community string, hash string, db Database) error {
bucket, err := db.GetBucket(community)
if err != nil {
return err
}
return bucket.Put(hash, seenMarker)
}
func ImageToHash(img image.Image) (string, error) {
coloredResized := image.NewRGBA(image.Rect(0, 0, 8, 8))
draw.NearestNeighbor.Scale(coloredResized, coloredResized.Rect, img, img.Bounds(), draw.Over, nil)
grayResized := image.NewGray(coloredResized.Bounds())
for y := coloredResized.Bounds().Min.Y; y < coloredResized.Bounds().Max.Y; y++ {
for x := coloredResized.Bounds().Min.X; x < coloredResized.Bounds().Max.X; x++ {
grayResized.Set(x, y, coloredResized.At(x, y))
}
}
var pixelSum uint64
for y := grayResized.Bounds().Min.Y; y < grayResized.Bounds().Max.Y; y++ {
for x := grayResized.Bounds().Min.X; x < grayResized.Bounds().Max.Y; x++ {
pixel := grayResized.GrayAt(x, y)
value := pixel.Y
pixelSum += uint64(value)
}
}
totalPixels := uint64(grayResized.Bounds().Dx() * grayResized.Bounds().Dy())
avgValue := uint8(pixelSum / totalPixels)
var imageHash uint64
for y := grayResized.Bounds().Min.Y; y < grayResized.Bounds().Max.Y; y++ {
for x := grayResized.Bounds().Min.X; x < grayResized.Bounds().Max.Y; x++ {
pixel := grayResized.GrayAt(x, y)
value := pixel.Y
if value > avgValue {
hashIndex := (y * 8) + x
imageHash |= (1 << hashIndex)
}
}
}
return fmt.Sprintf("%016x", imageHash), nil
}