File: rgb.go

package info (click to toggle)
golang-gopkg-go-playground-colors.v1 1.2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 116 kB
  • sloc: makefile: 2
file content (103 lines) | stat: -rw-r--r-- 2,795 bytes parent folder | download | duplicates (2)
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
package colors

import (
	"fmt"
	"math"
	"regexp"
	"strconv"
	"strings"
)

const (
	rgbString                    = "rgb(%d,%d,%d)"
	rgbCaptureRegexString        = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*\\)$"
	rgbCaptureRegexPercentString = "^rgb\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*\\)$"
)

var (
	rgbCaptureRegex        = regexp.MustCompile(rgbCaptureRegexString)
	rgbCapturePercentRegex = regexp.MustCompile(rgbCaptureRegexPercentString)
)

// RGBColor represents an RGB color
type RGBColor struct {
	R uint8
	G uint8
	B uint8
}

// ParseRGB validates an parses the provided string into an RGBColor object
// supports both RGB 255 and RGB as percentages
func ParseRGB(s string) (*RGBColor, error) {

	s = strings.ToLower(s)

	var isPercent bool
	vals := rgbCaptureRegex.FindAllStringSubmatch(s, -1)

	if vals == nil || len(vals) == 0 || len(vals[0]) == 0 {

		vals = rgbCapturePercentRegex.FindAllStringSubmatch(s, -1)

		if vals == nil || len(vals) == 0 || len(vals[0]) == 0 {
			return nil, ErrBadColor
		}

		isPercent = true
	}

	r, _ := strconv.ParseUint(vals[0][1], 10, 8)
	g, _ := strconv.ParseUint(vals[0][2], 10, 8)
	b, _ := strconv.ParseUint(vals[0][3], 10, 8)

	if isPercent {
		r = uint64(math.Floor(float64(r)/100*255 + .5))
		g = uint64(math.Floor(float64(g)/100*255 + .5))
		b = uint64(math.Floor(float64(b)/100*255 + .5))
	}

	return &RGBColor{R: uint8(r), G: uint8(g), B: uint8(b)}, nil
}

// RGB validates and returns a new RGBColor object from the provided r, g, b values
func RGB(r, g, b uint8) (*RGBColor, error) {
	return &RGBColor{R: r, G: g, B: b}, nil
}

// String returns the string representation on the RGBColor
func (c *RGBColor) String() string {
	return fmt.Sprintf(rgbString, c.R, c.G, c.B)
}

// ToHEX converts the RGBColor to a HEXColor
func (c *RGBColor) ToHEX() *HEXColor {
	return &HEXColor{hex: fmt.Sprintf("#%02x%02x%02x", c.R, c.G, c.B)}
}

// ToRGB converts the RGBColor to an RGBColor
// it's here to satisfy the Color interface
func (c *RGBColor) ToRGB() *RGBColor {
	return c
}

// ToRGBA converts the RGBColor to an RGBAColor
func (c *RGBColor) ToRGBA() *RGBAColor {
	return &RGBAColor{R: c.R, G: c.G, B: c.B, A: 1}
}

// IsLight returns whether the color is perceived to be a light color
func (c *RGBColor) IsLight() bool {

	r := float64(c.R)
	g := float64(c.G)
	b := float64(c.B)

	hsp := math.Sqrt(0.299*math.Pow(r, 2) + 0.587*math.Pow(g, 2) + 0.114*math.Pow(b, 2))

	return hsp > 130
}

// IsDark returns whether the color is perceived to be a dark color
func (c *RGBColor) IsDark() bool {
	return !c.IsLight()
}