diff options
Diffstat (limited to 'internal/colors')
-rw-r--r-- | internal/colors/cmyk.go | 46 | ||||
-rw-r--r-- | internal/colors/hsl.go | 1 | ||||
-rw-r--r-- | internal/colors/precise.go | 38 | ||||
-rw-r--r-- | internal/colors/rgb.go | 25 |
4 files changed, 110 insertions, 0 deletions
diff --git a/internal/colors/cmyk.go b/internal/colors/cmyk.go new file mode 100644 index 0000000..3460c4e --- /dev/null +++ b/internal/colors/cmyk.go @@ -0,0 +1,46 @@ +package colors + +import "math" + +type CMYK struct { + C int // 0-100 + M int // 0-100 + Y int // 0-100 + K int // 0-100 +} + +func (c CMYK) ToPrecise() PreciseColor { + return PreciseColor{ + R: (1 - float64(c.C)/100) * (1 - float64(c.K)/100), + G: (1 - float64(c.M)/100) * (1 - float64(c.K)/100), + B: (1 - float64(c.Y)/100) * (1 - float64(c.K)/100), + } +} + +func (c CMYK) FromPrecise(p PreciseColor) ColorSpace { + // Extract RGB components from the PreciseColor + r := p.R + g := p.G + b := p.B + + // Calculate the K (key/black) component + k := 1 - math.Max(math.Max(r, g), b) + + // Avoid division by zero when K is 1 (pure black) + if k == 1 { + return CMYK{C: 0, M: 0, Y: 0, K: 100} + } + + // Calculate the CMY components based on the remaining color values + cyan := (1 - r - k) / (1 - k) + magenta := (1 - g - k) / (1 - k) + yellow := (1 - b - k) / (1 - k) + + // Scale to 0-100 and return + return CMYK{ + C: int(math.Round(cyan * 100)), + M: int(math.Round(magenta * 100)), + Y: int(math.Round(yellow * 100)), + K: int(math.Round(k * 100)), + } +} diff --git a/internal/colors/hsl.go b/internal/colors/hsl.go new file mode 100644 index 0000000..7477042 --- /dev/null +++ b/internal/colors/hsl.go @@ -0,0 +1 @@ +package colors diff --git a/internal/colors/precise.go b/internal/colors/precise.go new file mode 100644 index 0000000..fafa104 --- /dev/null +++ b/internal/colors/precise.go @@ -0,0 +1,38 @@ +package colors + +import ( + "fmt" + "math" + "strings" +) + +type ColorSpace interface { + ToPrecise() PreciseColor + FromPrecise(PreciseColor) ColorSpace +} + +// PreciseColor is a color with floating point values for red, green, and blue. +// The extra precision minimizes rounding errors when converting between different +// color spaces. It is used as an intermediate representation when converting between +// different color spaces. +type PreciseColor struct { + R, G, B float64 +} + +func (c PreciseColor) ToPrecise() PreciseColor { + return c +} + +func (c PreciseColor) FromPrecise(p PreciseColor) ColorSpace { + return p +} + +func ToHexString(cs ColorSpace) string { + p := cs.ToPrecise() + + return strings.ToUpper(fmt.Sprintf("#%02x%02x%02x", + int(math.Round(p.R*255)), + int(math.Round(p.G*255)), + int(math.Round(p.B*255)), + )) +} diff --git a/internal/colors/rgb.go b/internal/colors/rgb.go new file mode 100644 index 0000000..e81aefc --- /dev/null +++ b/internal/colors/rgb.go @@ -0,0 +1,25 @@ +package colors + +import "math" + +type RGB struct { + R int // 0-255 + G int // 0-255 + B int // 0-255 +} + +func (c RGB) ToPrecise() PreciseColor { + return PreciseColor{ + R: float64(c.R) / 255, + G: float64(c.G) / 255, + B: float64(c.B) / 255, + } +} + +func (c RGB) FromPrecise(p PreciseColor) ColorSpace { + return RGB{ + R: int(math.Round(p.R * 255)), + G: int(math.Round(p.G * 255)), + B: int(math.Round(p.B * 255)), + } +} |