我想将颜色元组转换为颜色名称,例如“黄色”或“蓝色”
>>> im = Image.open("test.jpg")
>>> n, color = max(im.getcolors(im.size[0]*im.size[1]))
>>> print color
(119, 172, 152)
Python 有没有简单的方法来做到这一点?
看起来 webcolors 可以让你做到这一点:
rgb_to_name(rgb_triplet,spec='css3')
将适用于 rgb() 颜色三元组的整数三元组转换为其相应的标准化颜色名称(如果存在任何此类名称);有效值为 html4、css2、css21 和 css3,默认为 css3。
示例:
>>> rgb_to_name((0, 0, 0))
'black'
反之亦然:
>>> name_to_rgb('navy')
(0, 0, 128)
#查找最接近的颜色名称:
但是,如果找不到与请求的颜色匹配的颜色,
webcolors
会引发异常。我编写了一个小修复程序,为请求的 RGB 颜色提供最接近的匹配名称。它通过 RGB 空间中的欧几里德距离进行匹配。
import webcolors
def closest_colour(requested_colour):
min_colours = {}
for key, name in webcolors.CSS3_HEX_TO_NAMES.items():
r_c, g_c, b_c = webcolors.hex_to_rgb(key)
rd = (r_c - requested_colour[0]) ** 2
gd = (g_c - requested_colour[1]) ** 2
bd = (b_c - requested_colour[2]) ** 2
min_colours[(rd + gd + bd)] = name
return min_colours[min(min_colours.keys())]
def get_colour_name(requested_colour):
try:
closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
except ValueError:
closest_name = closest_colour(requested_colour)
actual_name = None
return actual_name, closest_name
requested_colour = (119, 172, 152)
actual_name, closest_name = get_colour_name(requested_colour)
print("Actual colour name:", actual_name, ", closest colour name:", closest_name)
输出:
Actual colour name: None , closest colour name: cadetblue
对于像我一样想要更熟悉的颜色名称的人,您可以使用CSS 2.1颜色名称,也由
webcolors
提供:
#00ffff
#000000
#0000ff
#ff00ff
#008000
#808080
#00ff00
#800000
#000080
#808000
#800080
#ff0000
#c0c0c0
#008080
#ffffff
#ffff00
#ffa500
只需使用fraxel的优秀答案和代码即可获得最接近的颜色,适应CSS 2.1:
def get_colour_name(rgb_triplet):
min_colours = {}
for key, name in webcolors.css21_hex_to_names.items():
r_c, g_c, b_c = webcolors.hex_to_rgb(key)
rd = (r_c - rgb_triplet[0]) ** 2
gd = (g_c - rgb_triplet[1]) ** 2
bd = (b_c - rgb_triplet[2]) ** 2
min_colours[(rd + gd + bd)] = name
return min_colours[min(min_colours.keys())]
有一个名为 pynche 的程序,可以将 RGB 更改为 Python 的英文颜色名称。
你可以尝试使用
ColorDB.nearest()
中的方法ColorDB.py
,它可以做到你想要的。
您可以在这里找到有关此方法的更多信息:ColorDB Pynche
问题的解决方案是将 RGB 值映射到 HSL 颜色空间。
在 HSL 颜色空间中获得颜色后,您可以使用 H(色调)分量将其映射为颜色。请注意,颜色是一个有点主观的概念,因此您必须定义 H 的哪些范围对应于给定颜色。
我会用字典找出基色,然后找到最接近的。:
def get_color_name(rgb):
colors = {
"red": (255, 0, 0),
"green": (0, 255, 0),
"blue": (0, 0, 255),
"yellow": (255, 255, 0),
"magenta": (255, 0, 255),
"cyan": (0, 255, 255),
"black": (0, 0, 0),
"white": (255, 255, 255)
}
min_distance = float("inf")
closest_color = None
for color, value in colors.items():
distance = sum([(i - j) ** 2 for i, j in zip(rgb, value)])
if distance < min_distance:
min_distance = distance
closest_color = color
return closest_color
# Testing
print(get_color_name((255, 0, 0))) # red
print(get_color_name((0, 255, 0))) # green
print(get_color_name((0, 0, 255))) # blue
我发现解决此问题的最佳解决方案是 tux21b 在这篇文章中提供的解决方案:
从十六进制颜色代码中查找颜色名称
通过我所做的修复(以避免被零除错误)。
(根据我的理解)这是一种近似计算,不需要加载大量数据表来获得接近的值,并且允许设置您自己的一组所需的颜色。
2024 年 6 月更新
截至 2024 年 6 月,webcolors 的维护者从公共界面中删除了颜色列表。 v24.6.0 变更日志中的最后一个项目符号解释了this。
遵循上面 @fraxel 和 @fiatjaf 的优秀答案的模式,这个更新版本将颜色名称列表替换为本地定义的内容。
def get_colour_name(rgb_triplet):
myColors = {
"red" : "#ff0000", # R
"orange" : "#ffa500", # O
"yellow" : "#ffff00", # Y
"green" : "#008000", # G
"blue" : "#0000ff", # B
"magenta" : "#ff00ff", # I
"purple" : "#800080", # V
"coral" : "#ff7f50", # light red
"maroon" : "#800000", # dark red
"navy" : "#000080", # dark blue
"cyan" : "#00ffff", # light blue
"gold" : "#ffd700", # dark yellow
"lime" : "#00ff00", # bright green
"jade" : "#00a36c", # light green
"olive" : "#808000", # dark green
"grey" : "#808080" }
min_colours = {}
for name, hex_val in myColors.items():
r_c, g_c, b_c = webcolors.hex_to_rgb(hex_val)
rd = (r_c - rgb_triplet[0]) ** 2
gd = (g_c - rgb_triplet[1]) ** 2
bd = (b_c - rgb_triplet[2]) ** 2
min_colours[(rd + gd + bd)] = name
return min_colours[min(min_colours.keys())]
# what is the name for this kml color???
kml_color='ffffff00' # kml colors are non-standard:
aabbggrr (alpha, blue, green, red)
kml_color='ff00eb00' # this is kml for green
# convert to RGB on [0 255]
alpha=int( kml_color[0:2] , 16)
blu =int( kml_color[2:4] , 16)
grn =int( kml_color[4:6] , 16)
red =int( kml_color[6:] , 16)
print(f'kml_color={kml_color} --> RGB=({red},{grn},{blu}), alpha={alpha}')
closest_colorname = get_colour_name((red, grn, blu))
print(f'the closest CSS color to {kml_color}, which is
RGB={red},{grn},{blu} is {closest_colorname}')