在这里处理 Jeremy 的回复:Converting hex color to RGB and vice-versa 我能够获得一个 python 程序来转换预设颜色的十六进制代码(例如 #B4FBB8),但是从最终用户的角度来看,我们不能要求人们编辑代码 &从那里跑。如何提示用户输入一个十六进制值,然后让它从那里吐出一个 RGB 值?
这是我到目前为止的代码:
def hex_to_rgb(value):
value = value.lstrip('#')
lv = len(value)
return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
def rgb_to_hex(rgb):
return '#%02x%02x%02x' % rgb
hex_to_rgb("#ffffff") # ==> (255, 255, 255)
hex_to_rgb("#ffffffffffff") # ==> (65535, 65535, 65535)
rgb_to_hex((255, 255, 255)) # ==> '#ffffff'
rgb_to_hex((65535, 65535, 65535)) # ==> '#ffffffffffff'
print('Please enter your colour hex')
hex == input("")
print('Calculating...')
print(hex_to_rgb(hex()))
使用行 print(hex_to_rgb('#B4FBB8'))
我可以让它吐出正确的 RGB 值,即 (180, 251, 184)
这可能非常简单——我对 Python 还是很陌生。
我相信这可以满足您的需求:
h = input('Enter hex: ').lstrip('#')
print('RGB =', tuple(int(h[i:i+2], 16) for i in (0, 2, 4)))
(以上是为 Python 3 编写的)
样品运行:
Enter hex: #B4FBB8
RGB = (180, 251, 184)
写入文件
要在保留格式的同时使用句柄 fhandle
写入文件:
fhandle.write('RGB = {}'.format( tuple(int(h[i:i+2], 16) for i in (0, 2, 4)) ))
您可以使用 Pillow 中的 ImageColor
。
>>> from PIL import ImageColor
>>> ImageColor.getcolor("#23a9dd", "RGB")
(35, 169, 221)
只是另一个选项:matplotlib.colors 模块。
非常简单:
>>> import matplotlib.colors
>>> matplotlib.colors.to_rgb('#B4FBB8')
(0.7058823529411765, 0.984313725490196, 0.7215686274509804)
请注意,to_rgb
的输入不必是十六进制颜色格式,它允许多种颜色格式。
您还可以使用已弃用的 hex2color
>>> matplotlib.colors.hex2color('#B4FBB8')
(0.7058823529411765, 0.984313725490196, 0.7215686274509804)
好处是我们有反函数 to_hex
和一些额外的函数,例如 rgb_to_hsv
。
一个懒惰的选择:webcolors 包有一个 hex_to_rgb
函数。
hex_to_rgb
,其中元组以十进制值在 0 和 1 范围内指定(例如 hex_to_rgb_decimal)。但是,您可以使用导入 numpy 和 webcolors 的代码:tuple(numpy.array(webcolors.hex_to_rgb('#9C0006'))/255.0)
PIL 也有这个功能,在 ImageColor 中。
from PIL import ImageColor
ImageColor.getrgb("#9b9b9b")
如果你想要从 0 到 1 的数字
[i/256 for i in ImageColor.getrgb("#9b9b9b")]
ImageColor.getrbb
返回的值是 [0 ... 255],上限为 255。通过除以 256,您将永远不会达到 1.0。除非我在这里非常错误,否则我建议您将其更改为 i/255。
此函数将从十六进制代码返回浮点中的 RGB 值。
def hextofloats(h):
'''Takes a hex rgb string (e.g. #ffffff) and returns an RGB tuple (float, float, float).'''
return tuple(int(h[i:i + 2], 16) / 255. for i in (1, 3, 5)) # skip '#'
此函数将从 RGB 值返回十六进制代码。
def floatstohex(rgb):
'''Takes an RGB tuple or list and returns a hex RGB string.'''
return f'#{int(rgb[0]*255):02x}{int(rgb[1]*255):02x}{int(rgb[2]*255):02x}'
因为 HEX 代码可以像 "#FFF"
、"#000"
、"#0F0"
甚至 "#ABC"
,它们只使用三个数字。 这些只是写作的速记版本一个代码,它们是三对相同的数字 "#FFFFFF"
、"#000000"
、"#00FF00"
或 "#AABBCC"
。
此函数的制作方式使其既可以使用速记也可以使用完整的 HEX 代码。如果参数 hsl = False
则返回 RGB 值,否则返回 HSL 值。
import re
def hex_to_rgb(hx, hsl=False):
"""Converts a HEX code into RGB or HSL.
Args:
hx (str): Takes both short as well as long HEX codes.
hsl (bool): Converts the given HEX code into HSL value if True.
Return:
Tuple of length 3 consisting of either int or float values.
Raise:
ValueError: If given value is not a valid HEX code."""
if re.compile(r'#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$').match(hx):
div = 255.0 if hsl else 0
if len(hx) <= 4:
return tuple(int(hx[i]*2, 16) / div if div else
int(hx[i]*2, 16) for i in (1, 2, 3))
return tuple(int(hx[i:i+2], 16) / div if div else
int(hx[i:i+2], 16) for i in (1, 3, 5))
raise ValueError(f'"{hx}" is not a valid HEX code.')
这是一些空闲输出。
>>> hex_to_rgb('#FFB6C1')
(255, 182, 193)
>>> hex_to_rgb('#ABC')
(170, 187, 204)
>>> hex_to_rgb('#FFB6C1', hsl=True)
(1.0, 0.7137254901960784, 0.7568627450980392)
>>> hex_to_rgb('#ABC', hsl=True)
(0.6666666666666666, 0.7333333333333333, 0.8)
>>> hex_to_rgb('#00FFFF')
(0, 255, 255)
>>> hex_to_rgb('#0FF')
(0, 255, 255)
>>> hex_to_rgb('#0FFG') # When invalid hex is given.
ValueError: "#0FFG" is not a valid HEX code.
以下函数将十六进制字符串转换为 rgb 值:
def hex_to_rgb(hex_string):
r_hex = hex_string[1:3]
g_hex = hex_string[3:5]
b_hex = hex_string[5:7]
return int(r_hex, 16), int(g_hex, 16), int(b_hex, 16)
这会将 hexadecimal_string 转换为十进制数
int(hex_string, 16)
例如:
int('ff', 16) # Gives 255 in integer data type
这里有两个小错误!
hex == input("")
应该:
user_hex = input("")
您想将 input()
的输出分配给 hex
,而不是检查比较。此外,正如评论 (@koukouviou) 中所述,不要覆盖 hex
,而是将其称为 user_hex
。
还:
print(hex_to_rgb(hex()))
应该:
print(hex_to_rgb(user_hex))
您想使用十六进制的值,而不是类型的可调用方法 (__call__
)。
hex
。也许像 hex_in
或类似的东西更好
我见过的所有答案都涉及对十六进制字符串的操作。在我看来,我更喜欢使用编码整数和 RGB 三元组本身,而不仅仅是字符串。这样做的好处是不需要用十六进制表示颜色——它可以是八进制、二进制、十进制,你有什么。
将 RGB 三元组转换为整数很容易。
rgb = (0xc4, 0xfb, 0xa1) # (196, 251, 161)
def rgb2int(r,g,b):
return (256**2)*r + 256*g + b
c = rgb2int(*rgb) # 12909473
print(hex(c)) # '0xc4fba1'
我们需要更多的数学来计算相反的方向。我已从对类似 Math exchange question 的回答中提取了以下内容。
c = 0xc4fba1
def int2rgb(n):
b = n % 256
g = int( ((n-b)/256) % 256 ) # always an integer
r = int( ((n-b)/256**2) - g/256 ) # ditto
return (r,g,b)
print(tuple(map(hex, int2rgb(c)))) # ('0xc4', '0xfb', '0xa1')
使用这种方法,您可以轻松地与字符串相互转换。
尝试这个:
def rgb_to_hex(rgb):
return '%02x%02x%02x' % rgb
用法:
>>> rgb_to_hex((255, 255, 195))
'ffffc3'
而反过来:
def hex_to_rgb(hexa):
return tuple(int(hexa[i:i+2], 16) for i in (0, 2, 4))
用法:
>>> hex_to_rgb('ffffc3')
(255, 255, 195)
您的方法的问题是用户可以输入多种格式的十六进制代码,例如:
带或不带井号(#ff0000 或 ff0000)
大写或小写 (#ff0000, #FF0000)
包括或不包括透明度(#ffff0000 或 #ff0000ff 或 #ff0000)
colorir 可用于在颜色系统之间进行格式化和转换:
from colorir import HexRGB, sRGB
user_input = input("Enter the hex code:")
rgb = HexRGB(user_input).rgb() # This is safe for pretty much any hex format
for i in (0, 2, 4)))
f.write
的字符串格式更新了答案。2.7.12
时,我使用的是未来的print
,我忘记了其他人的所有问题。