Conversion d'un tuple de couleur RVB en un code à six chiffres, en Python
87
J'ai besoin de convertir (0, 128, 64) en quelque chose comme ceci # 008040. Je ne sais pas comment appeler ce dernier, ce qui rend la recherche difficile.
Voir la réponse précédente du SO stackoverflow.com/questions/214359/… - parmi les trois réponses, celle avec le plus de votes comprend un extrait de code Python pour faire ce que je pense que vous recherchez.
La limite à 2 chiffres est-elle vraiment nécessaire? Tant que les valeurs RVB sont dans les limites appropriées de 0 à 255, vous ne devriez pas en avoir besoin. Donc, vous pouvez simplement faire'#%x%x%x' % (r, g, b)
mots pour
3
En fait maintenant, je vois que si vous avez une valeur de 0, il doit être complété par un autre 0. Ainsi, le 02 pour en faire deux chiffres.
Cela utilise la méthode préférée de formatage de chaîne, comme décrit dans PEP 3101 . Il utilise également min()et maxpour garantir cela 0 <= {r,g,b} <= 255.
La mise à jour a ajouté la fonction de serrage comme suggéré ci-dessous.
Mise à jour À partir du titre de la question et du contexte donné, il devrait être évident que cela attend 3 pouces dans [0,255] et renverra toujours une couleur lorsqu'il est passé 3 pouces de ce type. Cependant, d'après les commentaires, cela peut ne pas être évident pour tout le monde, alors laissez-le être explicitement déclaré:
Si trois intvaleurs sont fournies , cela renverra un triplet hexadécimal valide représentant une couleur. Si ces valeurs sont comprises entre [0,255], il les traitera comme des valeurs RVB et renverra la couleur correspondant à ces valeurs.
C'est une vieille question mais pour information, j'ai développé un package avec quelques utilitaires liés aux couleurs et aux couleurs et contient la fonction rgb2hex que vous cherchiez à convertir triplet en valeur hexa (qui peut être trouvée dans de nombreux autres packages, par exemple matplotlib). C'est sur pypi
pip install colormap
puis
>>> from colormap import rgb2hex
>>> rgb2hex(0, 128, 64)
'##008040'
La validité des entrées est vérifiée (les valeurs doivent être comprises entre 0 et 255).
Notez que cela ne fonctionne qu'avec python3.6 et supérieur.
defrgb2hex(color):"""Converts a list or tuple of color to an RGB string
Args:
color (list|tuple): the list or tuple of integers (e.g. (127, 127, 127))
Returns:
str: the rgb string
"""returnf"#{''.join(f'{hex(c)[2:].upper():0>2}'for c in color)}"
Ce qui précède est l'équivalent de:
defrgb2hex(color):
string = '#'for value in color:
hex_string = hex(value) # e.g. 0x7f
reduced_hex_string = hex_string[2:] # e.g. 7f
capitalized_hex_string = reduced_hex_string.upper() # e.g. 7F
string += capitalized_hex_string # e.g. #7F7F7Freturn string
Cette fonction rgb2hex, appliquée à (13,13,12), donne 0xDDC, mais le site Web RGB to HEX le donne comme 0x0D0D0C, et cela concorde également avec l'idée que le nombre devrait être 13 * 65536 + 13 * 256 + 12, et 0xDDC est lu par Python comme 3548.
Lars Ericson
Les couleurs CSS sont incohérentes. Il y a des couleurs hexadécimales à 6 chiffres, des couleurs hexadécimales à 3 chiffres, une notation RVB avec décimales et pourcentages, hsl, etc. J'ai modifié la formule pour toujours fournir des couleurs hexadécimales à 6 chiffres, et même si je pense que cela peut être plus cohérent, je Je ne suis pas sûr que ce soit plus correct.
Brian Bruggeman
3
vous pouvez utiliser des chaînes lambda et f (disponible en python 3.6+)
L'appel direct de lambda n'est pas recommandé pour une foule de raisons. Je les ai utilisés comme ça sur un projet qui a été revu et tout le monde a dit la même chose, de ne pas appeler directement.
Je sais que les one-liners en Python ne sont pas forcément appréciés. Mais il y a des moments où je ne peux pas résister à profiter de ce que permet l'analyseur Python. C'est la même réponse que la solution de Dietrich Epp (la meilleure), mais enveloppée dans une fonction sur une seule ligne. Alors, merci Dietrich!
Voici une fonction plus complète pour gérer les situations dans lesquelles vous pouvez avoir des valeurs RVB dans la plage [0,1] ou la plage [0,255] .
defRGBtoHex(vals, rgbtype=1):"""Converts RGB values in a variety of formats to Hex values.
@param vals An RGB/RGBA tuple
@param rgbtype Valid valus are:
1 - Inputs are in the range 0 to 1
256 - Inputs are in the range 0 to 255
@return A hex string in the form '#RRGGBB' or '#RRGGBBAA'
"""if len(vals)!=3and len(vals)!=4:
raise Exception("RGB or RGBA inputs to RGBtoHex must have three or four elements!")
if rgbtype!=1and rgbtype!=256:
raise Exception("rgbtype must be 1 or 256!")
#Convert from 0-1 RGB/RGBA to 0-255 RGB/RGBAif rgbtype==1:
vals = [255*x for x in vals]
#Ensure values are rounded integers, convert to hex, and concatenatereturn'#' + ''.join(['{:02X}'.format(int(round(x))) for x in vals])
print(RGBtoHex((0.1,0.3, 1)))
print(RGBtoHex((0.8,0.5, 0)))
print(RGBtoHex(( 3, 20,147), rgbtype=256))
print(RGBtoHex(( 3, 20,147,43), rgbtype=256))
Vous pouvez également utiliser des opérateurs peu judicieux, ce qui est assez efficace, même si je doute que vous vous inquiétiez de l'efficacité avec quelque chose comme ça. C'est aussi relativement propre. Notez qu'il ne serre pas ou ne vérifie pas les limites. Cela est pris en charge depuis au moins Python 2.7.17 .
hex(r << 16 | g << 8 | b)
Et pour le changer pour qu'il commence par un #, vous pouvez faire:
Réponses:
Utilisez l'opérateur de format
%
:>>> '#%02x%02x%02x' % (0, 128, 64) '#008040'
Notez qu'il ne vérifie pas les limites ...
>>> '#%02x%02x%02x' % (0, -1, 9999) '#00-1270f'
la source
'#%x%x%x' % (r, g, b)
def clamp(x): return max(0, min(x, 255)) "#{0:02x}{1:02x}{2:02x}".format(clamp(r), clamp(g), clamp(b))
Cela utilise la méthode préférée de formatage de chaîne, comme décrit dans PEP 3101 . Il utilise également
min()
etmax
pour garantir cela0 <= {r,g,b} <= 255
.La mise à jour a ajouté la fonction de serrage comme suggéré ci-dessous.
Mise à jour À partir du titre de la question et du contexte donné, il devrait être évident que cela attend 3 pouces dans [0,255] et renverra toujours une couleur lorsqu'il est passé 3 pouces de ce type. Cependant, d'après les commentaires, cela peut ne pas être évident pour tout le monde, alors laissez-le être explicitement déclaré:
la source
C'est une vieille question mais pour information, j'ai développé un package avec quelques utilitaires liés aux couleurs et aux couleurs et contient la fonction rgb2hex que vous cherchiez à convertir triplet en valeur hexa (qui peut être trouvée dans de nombreux autres packages, par exemple matplotlib). C'est sur pypi
puis
>>> from colormap import rgb2hex >>> rgb2hex(0, 128, 64) '##008040'
La validité des entrées est vérifiée (les valeurs doivent être comprises entre 0 et 255).
la source
J'ai créé un programme Python complet pour cela, les fonctions suivantes peuvent convertir rgb en hexadécimal et vice versa.
def rgb2hex(r,g,b): return "#{:02x}{:02x}{:02x}".format(r,g,b) def hex2rgb(hexcode): return tuple(map(ord,hexcode[1:].decode('hex')))
Vous pouvez voir le code complet et le didacticiel sur le lien suivant: Conversion RVB vers Hex et Hex vers RVB avec Python
la source
triplet = (0, 128, 64) print '#'+''.join(map(chr, triplet)).encode('hex')
ou
from struct import pack print '#'+pack("BBB",*triplet).encode('hex')
python3 est légèrement différent
from base64 import b16encode print(b'#'+b16encode(bytes(triplet)))
la source
Notez que cela ne fonctionne qu'avec python3.6 et supérieur.
def rgb2hex(color): """Converts a list or tuple of color to an RGB string Args: color (list|tuple): the list or tuple of integers (e.g. (127, 127, 127)) Returns: str: the rgb string """ return f"#{''.join(f'{hex(c)[2:].upper():0>2}' for c in color)}"
Ce qui précède est l'équivalent de:
def rgb2hex(color): string = '#' for value in color: hex_string = hex(value) # e.g. 0x7f reduced_hex_string = hex_string[2:] # e.g. 7f capitalized_hex_string = reduced_hex_string.upper() # e.g. 7F string += capitalized_hex_string # e.g. #7F7F7F return string
la source
vous pouvez utiliser des chaînes lambda et f (disponible en python 3.6+)
rgb2hex = lambda r,g,b: f"#{r:02x}{g:02x}{b:02x}" hex2rgb = lambda hx: (int(hx[0:2],16),int(hx[2:4],16),int(hx[4:6],16))
usage
rgb2hex(r,g,b) #output = #hexcolor hex2rgb("#hex") #output = (r,g,b) hexcolor must be in #hex format
la source
def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue) background = RGB(0, 128, 64)
Je sais que les one-liners en Python ne sont pas forcément appréciés. Mais il y a des moments où je ne peux pas résister à profiter de ce que permet l'analyseur Python. C'est la même réponse que la solution de Dietrich Epp (la meilleure), mais enveloppée dans une fonction sur une seule ligne. Alors, merci Dietrich!
Je l'utilise maintenant avec tkinter :-)
la source
Voici une fonction plus complète pour gérer les situations dans lesquelles vous pouvez avoir des valeurs RVB dans la plage [0,1] ou la plage [0,255] .
def RGBtoHex(vals, rgbtype=1): """Converts RGB values in a variety of formats to Hex values. @param vals An RGB/RGBA tuple @param rgbtype Valid valus are: 1 - Inputs are in the range 0 to 1 256 - Inputs are in the range 0 to 255 @return A hex string in the form '#RRGGBB' or '#RRGGBBAA' """ if len(vals)!=3 and len(vals)!=4: raise Exception("RGB or RGBA inputs to RGBtoHex must have three or four elements!") if rgbtype!=1 and rgbtype!=256: raise Exception("rgbtype must be 1 or 256!") #Convert from 0-1 RGB/RGBA to 0-255 RGB/RGBA if rgbtype==1: vals = [255*x for x in vals] #Ensure values are rounded integers, convert to hex, and concatenate return '#' + ''.join(['{:02X}'.format(int(round(x))) for x in vals]) print(RGBtoHex((0.1,0.3, 1))) print(RGBtoHex((0.8,0.5, 0))) print(RGBtoHex(( 3, 20,147), rgbtype=256)) print(RGBtoHex(( 3, 20,147,43), rgbtype=256))
la source
Dans Python 3.6 , vous pouvez utiliser des chaînes f pour rendre ce nettoyeur:
rgb = (0,128, 64) f'#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}'
Bien sûr, vous pouvez mettre cela dans une fonction , et en prime, les valeurs sont arrondies et converties en int :
def rgb2hex(r,g,b): return f'#{int(round(r)):02x}{int(round(g)):02x}{int(round(b)):02x}' rgb2hex(*rgb)
la source
Vous pouvez également utiliser des opérateurs peu judicieux, ce qui est assez efficace, même si je doute que vous vous inquiétiez de l'efficacité avec quelque chose comme ça. C'est aussi relativement propre. Notez qu'il ne serre pas ou ne vérifie pas les limites. Cela est pris en charge depuis au moins Python 2.7.17 .
hex(r << 16 | g << 8 | b)
Et pour le changer pour qu'il commence par un #, vous pouvez faire:
"#" + hex(243 << 16 | 103 << 8 | 67)[2:]
la source
Je suis vraiment surpris que personne n'ait suggéré cette approche:
Pour Python 2 et 3:
'#' + ''.join('{:02X}'.format(i) for i in colortuple)
Python 3.6+:
'#' + ''.join(f'{i:02X}' for i in colortuple)
En tant que fonction:
def hextriplet(colortuple): return '#' + ''.join(f'{i:02X}' for i in colortuple) color = (0, 128, 64) print(hextriplet(color))
la source
Il existe un package appelé webcolors. https://github.com/ubernostrum/webcolors
Il a une méthode
webcolors.rgb_to_hex
>>> import webcolors >>> webcolors.rgb_to_hex((12,232,23)) '#0ce817'
la source