-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcolournamer.go
104 lines (86 loc) · 2.69 KB
/
colournamer.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 colournamer
import (
"errors"
"image/color"
"sort"
"github.com/lucasb-eyer/go-colorful"
)
//go:generate go run ./cmd/colourgen -out colours.go
type Colour struct {
Name string
Colour colorful.Color
Distance float64
}
func (c Colour) String() string { return c.Name }
// Hex is the HTML hex representation of the colour.
func (c Colour) Hex() string { return c.Colour.Hex() }
// byDistance implements sort.Interface for []Colour based on Distance.
type byDistance []Colour
func (d byDistance) Len() int { return len(d) }
func (d byDistance) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (d byDistance) Less(i, j int) bool { return d[i].Distance < d[j].Distance }
// Results contains all colour matches, with each list containing an array of colours sorted by their similarity
// to the given colour.
type Results struct {
Basic []Colour
HTML []Colour
NTC []Colour
Pantone []Colour
ROYBGIV []Colour
}
// ClosestName returns the name of the colour whose RGB value is closest to the original value.
func (r Results) ClosestName() string {
var possibleNames []Colour
possibleNames = append(possibleNames, r.Basic[0])
possibleNames = append(possibleNames, r.HTML[0])
possibleNames = append(possibleNames, r.NTC[0])
possibleNames = append(possibleNames, r.Pantone[0])
possibleNames = append(possibleNames, r.ROYBGIV[0])
sort.Sort(byDistance(possibleNames))
return possibleNames[0].Name
}
func compute(source colorful.Color, list []Colour) []Colour {
var r []Colour
for _, colour := range list {
colour.Distance = colour.Colour.DistanceRgb(source)
r = append(r, colour)
}
sort.Sort(byDistance(r))
return r
}
// FromHex takes a hex RGB string and returns the closest colour name.
func FromHex(hex string) (Results, error) {
c, err := colorful.Hex(hex)
if err != nil {
return Results{}, err
}
results := Results{
Basic: compute(c, Basic),
HTML: compute(c, HTML),
NTC: compute(c, NTC),
Pantone: compute(c, Pantone),
ROYBGIV: compute(c, ROYGBIV),
}
return results, nil
}
// FromRGB takes RGB values and returns the closest colour name.
//
// The alpha value is set to 1. Use FromRGBA if you need to control the alpha.
func FromRGB(r, g, b uint8) (Results, error) {
return FromRGBA(r, g, b, 1)
}
// FromRGBA takes RGBA values and returns the closest colour name.
func FromRGBA(r, g, b, a uint8) (Results, error) {
c, ok := colorful.MakeColor(color.NRGBA{R: r, G: g, B: b, A: a})
if !ok || !c.IsValid() {
return Results{}, errors.New("invalid RGB")
}
results := Results{
Basic: compute(c, Basic),
HTML: compute(c, HTML),
NTC: compute(c, NTC),
Pantone: compute(c, Pantone),
ROYBGIV: compute(c, ROYGBIV),
}
return results, nil
}