1
0
forked from IPKM/nmreval
nmreval/nmreval/lib/colors.py
2022-03-28 16:28:15 +02:00

331 lines
8.1 KiB
Python

import enum
import re
from ..configs import config_paths
class BaseColor(enum.Enum):
def rgb(self, normed=False):
r, g, b = self.value
if normed:
return r/255., g/255., b/255
else:
return r, g, b
def hsl(self, normed=False):
r, g, b = self.rgb(normed=True)
col_max = max(r, g, b)
col_min = min(r, g, b)
delta = col_max - col_min
col_sum = col_max + col_min
lightness = col_sum / 2
if delta == 0:
hue = 1
saturation = 0
else:
try:
saturation = delta / (1 - abs(col_sum-1))
except ZeroDivisionError:
saturation = 0
if col_max == r:
hue = (g - b) / delta
elif col_max == g:
hue = (b - r) / delta + 2
elif col_max == b:
hue = (r - g) / delta + 4
else:
raise ValueError('convert to hsl failed')
hue *= 60.
if hue < 0:
hue += 360
if normed:
return hue/360, saturation, lightness
else:
return hue, saturation*255, lightness*255
def xyz(self):
rgb = list(self.rgb(normed=True))
for i, val in enumerate(rgb):
rgb[i] = ((val+0.055)/1.055)**2.4 if val > 0.04045 else val/12.92
x = sum(i*j for i, j in zip([0.4124, 0.3576, 0.1805], rgb))
y = sum(i*j for i, j in zip([0.2126, 0.7152, 0.0722], rgb))
z = sum(i*j for i, j in zip([0.0193, 0.1192, 0.9505], rgb))
return x, y, z
def hsv(self, normed=False):
r, g, b = self.rgb(normed=True)
col_max = max(r, g, b)
col_min = min(r, g, b)
delta = col_max - col_min
if delta == 0:
hue = 0
saturation = 0
else:
try:
saturation = delta / col_max
except ZeroDivisionError:
saturation = 0
if col_max == r:
hue = (g - b) / delta
elif col_max == g:
hue = (b - r) / delta + 2
elif col_max == b:
hue = (r - g) / delta + 4
else:
raise ValueError('convert to hsv failed')
hue *= 60.
if hue < 0:
hue += 360
if normed:
return hue / 360, saturation, col_max
else:
return hue, saturation * 255, col_max * 255
def lab(self):
x, y, z = self.xyz()
x /= 95.0489
y /= 100
z /= 108.884
x = x**(1 / 3) if x > 0.008856 else 7.787 * x + 16 / 116
y = y**(1 / 3) if y > 0.008856 else 7.787 * y + 16 / 116
z = z**(1 / 3) if z > 0.008856 else 7.787 * z + 16 / 116
l = 116 * y - 16
a = 500 * (x - y)
b = 200 * (x - z)
return l, a, b
def cmyk(self, normed=False):
r, g, b = self.rgb(normed=True)
k = 1. - max(r, g, b)
try:
c = (1. - r - k) / (1. - k)
m = (1. - g - k) / (1. - k)
y = (1. - b - k) / (1. - k)
except ZeroDivisionError:
c = m = y = 0.
if normed:
return c, m, y, k
else:
return c*255, m*255, y*255, k*255
@classmethod
def from_rgb(cls, r, g, b, normed=False):
if normed:
r *= 255
g *= 255
b *= 255
return cls((r, g, b))
@classmethod
def from_str(cls, hexstring):
r = int(hexstring[1:3], 16)
g = int(hexstring[3:5], 16)
b = int(hexstring[5:7], 16)
return cls((r, g, b))
class TUColorsA(BaseColor):
TuDa1a = (93, 133, 195)
TuDa2a = (0, 156, 218)
TuDa3a = (80, 182, 149)
TuDa4a = (175, 204, 80)
TuDa5a = (221, 223, 72)
TuDa6a = (255, 224, 92)
TuDa7a = (248, 186, 60)
TuDa8a = (238, 122, 52)
TuDa9a = (233, 80, 62)
TuDa10a = (201, 48, 142)
TuDa11a = (128, 69, 151)
class TUColorsB(BaseColor):
TuDa1b = (0, 90, 169)
TuDa2b = (0, 131, 204)
TuDa3b = (0, 157, 129)
TuDa4b = (153, 192, 0)
TuDa5b = (201, 212, 0)
TuDa6b = (253, 202, 0)
TuDa7b = (245, 163, 0)
TuDa8b = (236, 101, 0)
TuDa9b = (230, 0, 26)
TuDa10b = (166, 0, 132)
TuDa11b = (114, 16, 133)
class TUColorsC(BaseColor):
TuDa1c = (0, 78, 138)
TuDa2c = (0, 104, 157)
TuDa3c = (0, 136, 119)
TuDa4c = (127, 171, 22)
TuDa5c = (177, 189, 0)
TuDa6c = (215, 172, 0)
TuDa7c = (210, 135, 0)
TuDa8c = (204, 76, 3)
TuDa9c = (185, 15, 34)
TuDa10c = (149, 17, 105)
TuDa11c = (97, 28, 115)
class TUColorsD(BaseColor):
TuDa1d = (36, 53, 114)
TuDa2d = (0, 78, 115)
TuDa3d = (0, 113, 94)
TuDa4d = (106, 139, 55)
TuDa5d = (153, 166, 4)
TuDa6d = (174, 142, 0)
TuDa7d = (190, 111, 0)
TuDa8d = (169, 73, 19)
TuDa9d = (156, 28, 38)
TuDa10d = (115, 32, 84)
TuDa11d = (76, 34, 106)
class TUGrays(BaseColor):
TuDa0a = (220, 220, 220)
TuDa0b = (181, 181, 181)
TuDa0c = (137, 137, 137)
TuDa0d = (83, 83, 83)
White = (255, 255, 255)
Black = (0, 0, 0)
class RedBlue(BaseColor):
C1 = (103, 0, 31)
C2 = (178, 27, 43)
C3 = (178, 24, 43)
C4 = (244, 165, 130)
C5 = (253, 219, 199)
C6 = (220, 220, 220)
C7 = (253, 219, 199)
C8 = (146, 197, 222)
C9 = (67, 147, 195)
C10 = (33, 102, 172)
C11 = (5, 48, 97)
class Tab10(BaseColor):
TabBlue = (31, 119, 180)
TabOrange = (255, 127, 14)
TabGreen = (44, 160, 44)
TabRed = (214, 39, 40)
TabPurple = (148, 103, 189)
TabBrown = (140, 86, 75)
TabRose = (227, 119, 194)
TabGrey = (220, 220, 220)
TabChartreuse = (188, 189, 34)
TabTurquoise = (23, 190, 207)
class Tab20(BaseColor):
TabBlue = (31, 119, 180)
TabBlue2 = (174, 199, 232)
TabOrange = (255, 127, 14)
TabOrange2 = (255, 187, 120)
TabGreen = (44, 160, 44)
TabGreen2 = (152, 223, 138)
TabRed = (214, 39, 40)
TabRed2 = (255, 152, 150)
TabPurple = (148, 103, 189)
TabPurple2 = (197, 176, 213)
TabBrown = (140, 86, 75)
TabBrown2 = (196, 156, 148)
TabRose = (227, 119, 194)
TabRose2 = (247, 182, 210)
TabGrey = (220, 220, 220)
TabGrey2 = (199, 199, 199)
TabChartreuse = (188, 189, 34)
TabChartreuse2 = (219, 219, 141)
TabTurquoise = (23, 190, 207)
TabTurquoise2 = (158, 218, 229)
class GraceColors(BaseColor):
Red = (255, 0, 0)
Green = (0, 255, 0)
Blue = (0, 0, 255)
Yellow = (255, 255, 0)
Brown = (188, 143, 143)
Grey = (220, 220, 220)
Violet = (148, 0, 211)
Cyan = (0, 255, 255)
Magenta = (255, 0, 255)
Orange = (255, 255, 255)
Indigo = (114, 33, 188)
Maroon = (103, 7, 72)
Turquoise = (64, 224, 208)
Green4 = (0, 139, 0)
class BlackWhite(BaseColor):
White = (255, 255, 255)
Black = (0, 0, 0)
TUColors = enum.Enum(
value='TUColors',
names={member.name: member.value for palette in [TUColorsA, TUColorsB, TUColorsC, TUColorsD] for member in palette},
type=BaseColor,
)
Colors = enum.Enum(
value='Colors',
names={member.name: member.value for palette in [TUColors, TUGrays, GraceColors, Tab10, BlackWhite] for member in palette},
type=BaseColor,
)
def get_palettes():
palettes = {
'Full': Colors,
'TuDa:a': TUColorsA,
'TuDa:b': TUColorsB,
'TuDa:c': TUColorsC,
'TuDa:d': TUColorsD,
'Tab10': Tab10,
'Grace': GraceColors
}
with (config_paths() / 'colorschemes.cfg').open() as f:
palette_open = False
for line in f:
if line.startswith('%--'):
color_name = line[4:-1]
palette_open = True
color_list = []
continue
if palette_open:
m = re.match('(\d{1,3}.\d*), (\d{1,3}.\d*), (\d{1,3}.\d*)', line)
if m:
color_list.append(Colors.from_rgb(*(float(c) for c in m.groups())))
elif line == '\n':
palettes[color_name] = color_list
palette_open = False
return palettes