-
Notifications
You must be signed in to change notification settings - Fork 0
/
image_db.go
104 lines (90 loc) · 2.5 KB
/
image_db.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
package main
import (
"encoding/json"
"image"
"log"
"os"
)
type ImageRecord struct {
R int
G int
B int
Path string
}
type ImageDb struct {
images []ImageRecord
}
func (ip *ImageDb) Add(path string, r int, g int, b int) {
ip.images = append(ip.images, ImageRecord{r, g, b, path})
}
func (ip *ImageDb) Find(r int, g int, b int) string {
var bestMatch ImageRecord
var bestScore int = 255 * 255 * 3 + 1 //bigger than max calculatable score (lower is better)
for _, img := range ip.images {
score := SumSquares(r, g, b, img.R, img.G, img.B)
if score < bestScore {
bestScore = score
bestMatch = img
}
}
return bestMatch.Path
}
func SumSquares(r1 int, g1 int, b1 int, r2 int, g2 int, b2 int) int {
rdelta := r1 - r2
gdelta := g1 - g2
bdelta := b1 - b2
return rdelta * rdelta + gdelta * gdelta + bdelta * bdelta
}
const INDEX_FILE string = TILE_FILE_PATH + "index.json"
//Loads index of images from a json file
func (ip *ImageDb) loadIndex() bool {
indexFile, err := os.Open(INDEX_FILE)
if err != nil {
log.Print("Failed to load image db index from file.", err)
return false
}
defer indexFile.Close()
jsonParser := json.NewDecoder(indexFile)
if err = jsonParser.Decode(&ip.images); err != nil {
log.Print("Failed to parse image db index from file.", err)
return false
}
return len(ip.images) > 0
}
//Writes current image index to a json file
func (ip *ImageDb) writeIndex() {
indexFile, err := os.Create(INDEX_FILE)
if err != nil {
panic(err)
}
defer indexFile.Close()
encoder := json.NewEncoder(indexFile)
if err = encoder.Encode(ip.images); err != nil {
panic(err)
}
}
//Processes image files from a directory and indexes them
func (ip *ImageDb) reindex() {
filenames := ListSavedImages()
indexed := 0
for _, filename := range filenames {
img := ReadImageFromFile(filename)
if img == nil {
continue
}
bounds := img.Bounds()
r, g, b := Avg_color(img, image.Rect(bounds.Min.X, bounds.Min.Y, bounds.Max.X, bounds.Max.Y))
ip.Add(filename, r, g, b)
indexed++
log.Printf("Indexed %d images", indexed)
}
}
//Create instance of ImageDb populated with indexed images from a directory
func InitDb() *ImageDb {
imgDb := ImageDb{}
if !imgDb.loadIndex() {
imgDb.reindex()
imgDb.writeIndex()
}
return &imgDb
}