add a hex format color string parser

This commit is contained in:
Yongwei Xing 2022-01-26 16:09:05 +08:00
parent 2b7d135f55
commit 45b66f9f18

View file

@ -1,6 +1,10 @@
package common package common
import "image/color" import (
"fmt"
"image/color"
"strings"
)
var ( var (
MistyRose = color.RGBA{R: 0xFF, G: 0xE4, B: 0xE1, A: 0xFF} MistyRose = color.RGBA{R: 0xFF, G: 0xE4, B: 0xE1, A: 0xFF}
@ -114,3 +118,56 @@ var (
{R: 0xD2, G: 0xFD, B: 0xFF, A: 0xFF}, {R: 0xD2, G: 0xFD, B: 0xFF, A: 0xFF},
} }
) )
// ParseHexColor parses color string likes #FFFFFF or #2398EFFF
func ParseHexColor(s string) (color.RGBA, error) {
s = strings.TrimSpace(strings.ToLower(s))
if !strings.HasPrefix(s, "#") {
return Black, fmt.Errorf("invalid hex color string %v", s)
}
if c, ok := parseHex(s); ok {
return c, nil
}
return Black, fmt.Errorf("invalid hex color string %v", s)
}
// parseHex returns a color.RGBA by parsing a hex string
// Reference: https://stackoverflow.com/questions/54197913/parse-hex-string-to-image-color
func parseHex(s string) (color.RGBA, bool) {
c := color.RGBA{}
c.A = 1
ok := true
hexToByte := func(b byte) byte {
switch {
case b >= '0' && b <= '9':
return b - '0'
case b >= 'a' && b <= 'f':
return b - 'a' + 10
}
ok = false
return 0
}
n := len(s)
if n == 6 || n == 8 {
c.R = hexToByte(s[0])<<4+hexToByte(s[1])
c.G = hexToByte(s[2])<<4+hexToByte(s[3])
c.B = hexToByte(s[4])<<4+hexToByte(s[5])
if n == 8 {
c.A = hexToByte(s[6])<<4+hexToByte(s[7])
}
} else if n == 3 || n == 4 {
c.R = hexToByte(s[0])*17
c.G = hexToByte(s[1])*17
c.B = hexToByte(s[2])*17
if n == 4 {
c.A = hexToByte(s[3])*17
}
} else {
ok = false
}
return c, ok
}