/
color_label.go
96 lines (80 loc) · 2.12 KB
/
color_label.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
package overlay
import (
"fmt"
"image/color"
"math"
"strconv"
"strings"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
_ "golang.org/x/image/bmp"
)
// LabeledPixelToID converts the label-encoded pixel (e.g., #010101) which is
// alpha-premultiplied into an ID in the range of 0-255
func LabeledPixelToID(c color.Color) (uint32, error) {
// Find the color channel values for this pixel
pr, pg, pb, a := c.RGBA()
// Confirm that we're mapping ID 1 => #010101, etc
if pr != pg || pg != pb || pr != pb {
return 0, fmt.Errorf("Encoding expected to have equal values for R, G, and B. Instead, found %d, %d, %d", pr, pg, pb)
}
// Create the hex string representation. Since each color channel is
// "alpha-premultiplied" (https://golang.org/pkg/image/color/#RGBA),
// we need to divide by alpha (scaling 0-1), then multiplying by
// 255, to get what we're actually looking for
pixelID := uint32(math.Round(255 * float64(pr) / float64(a)))
return pixelID, nil
}
func rgbaFromColorCode(colorCode string) (color.Color, error) {
colorCode = strings.ReplaceAll(colorCode, "#", "")
// Special case the background
if len(colorCode) < 6 {
return color.RGBA{0, 0, 0, 0}, nil
}
// Parse each channel
r, err := strconv.ParseUint(colorCode[0:2], 16, 8)
if err != nil {
return nil, err
}
g, err := strconv.ParseUint(colorCode[2:4], 16, 8)
if err != nil {
return nil, err
}
b, err := strconv.ParseUint(colorCode[4:6], 16, 8)
if err != nil {
return nil, err
}
return color.RGBA{
R: uint8(r),
G: uint8(g),
B: uint8(b),
A: 255,
}, nil
}
func nrgbaFromColorCode(colorCode string) (color.Color, error) {
colorCode = strings.ReplaceAll(colorCode, "#", "")
// Special case the background
if len(colorCode) < 6 {
return color.RGBA{0, 0, 0, 0}, nil
}
// Parse each channel
r, err := strconv.ParseUint(colorCode[0:2], 16, 8)
if err != nil {
return nil, err
}
g, err := strconv.ParseUint(colorCode[2:4], 16, 8)
if err != nil {
return nil, err
}
b, err := strconv.ParseUint(colorCode[4:6], 16, 8)
if err != nil {
return nil, err
}
return color.NRGBA{
R: uint8(r),
G: uint8(g),
B: uint8(b),
A: 255,
}, nil
}