import re
from webcolors import html4_hex_to_names, hex_to_rgb, rgb_to_name, rgb_percent_to_hex, rgb_to_hex, css3_names_to_hex
from colorsys import hls_to_rgb
def closest_colour_rgb(requested_color):
min_colours = {}
for key, name in html4_hex_to_names.items():
r_c, g_c, b_c = hex_to_rgb(key)
rd = (r_c - requested_color[0]) ** 2
gd = (g_c - requested_color[1]) ** 2
bd = (b_c - requested_color[2]) ** 2
min_colours[(rd + gd + bd)] = name
return min_colours[min(min_colours.keys())]
def get_rgb_color_name(color):
try:
closest_name = actual_name = rgb_to_name(color, 'html4')
except ValueError:
closest_name = closest_colour_rgb(color)
actual_name = None
if actual_name:
return actual_name
else:
return closest_name
def get_hex_color_name(color):
try:
color = hex_to_rgb(color)
except ValueError:
return ''
try:
closest_name = actual_name = rgb_to_name(color, 'html4')
except ValueError:
closest_name = closest_colour_rgb(color)
actual_name = None
if actual_name:
return actual_name
else:
return closest_name
def str2closest_html_color_name(s: str):
if 'rgb' in s:
rgb_str = 'rgba' if ('rgba' in s) else 'rgb'
s = s.replace(rgb_str, '').replace('(', '').replace(')', '')
try:
rgb = [int(x) for x in s.split(',')[:3]]
rgb = tuple(rgb)
except ValueError:
return ''
if len(rgb) != 3:
return ''
name = get_rgb_color_name(rgb)
return name
elif '#' in s:
if s in ['#996A95', '#D5C9D3', '#E9E2E8', '#70416F']:
return 'purple'
if s in ['#FFD472', '#F47B4D', '#FFFBEF', '#F47B4D']:
return 'olive'
if s in ['#B0DFD7', '#EFF8F6', '#5CC4B7']:
return 'teal'
name = get_hex_color_name(s)
if (name == 'white') and (s.lower() not in ['#ffffff', '#fff']):
name = 'gray'
return name
elif s in html4_hex_to_names.items():
return s
else:
return ''
def str2hex(s: str):
if '#' in s:
return s
if ('rgb' in s) and ('%' in s):
rgb_str = 'rgba' if ('rgba' in s) else 'rgb'
s = s.replace(rgb_str, '').replace('(', '').replace(')', '')
rgb_percent = s.split(',')[:3]
hex_color = rgb_percent_to_hex(rgb_percent)
return hex_color
if 'rgb' in s:
rgb_str = 'rgba' if ('rgba' in s) else 'rgb'
s = s.replace(rgb_str, '').replace('(', '').replace(')', '')
try:
rgb = [int(x) for x in s.split(',')[:3]]
rgb = tuple(rgb)
except ValueError:
return ''
hex_color = rgb_to_hex(rgb)
return hex_color
if 'hsl' in s:
# hsl(hue in {0,360}, saturation [0, 100%], lightness [0, 100%])
match = re.search(r'hsla*\(((\d+), *(\d+)%, *(\d+)%(, \d\.\d)*)\)', s)
if match:
h, s, l = match.group(2), match.group(3), match.group(4)
h /= 360
s /= 10
l /= 100
rgb = tuple(hls_to_rgb(h, s, l))
return rgb_to_hex(rgb)
if s.lower() in css3_names_to_hex:
return css3_names_to_hex[s.lower()]
return ''
if __name__ == '__main__':
str2color_name('rgb(139, 0, 0)')
colors = [
(75, 0, 130), (255, 0, 255),
(139, 69, 19), (46, 139, 87),
(221, 160, 221)
]
hex_colors = [
'#96F', '#000', '#4C4C4C', '#A00', '#99F'
]
for c in colors:
n = get_rgb_color_name(c)
print("Actual colour:", c, ", closest colour name:", n)
for c in hex_colors:
n = get_hex_color_name(c)
print("Actual colour:", c, ", closest colour name:", n)
print()