Conversión de una tupla de color RGB en un código de seis dígitos, en Python


87

Necesito convertir (0, 128, 64) a algo como esto # 008040. No estoy seguro de cómo llamar a este último, lo que dificulta la búsqueda.


Consulte la respuesta de SO anterior stackoverflow.com/questions/214359/… - de las tres respuestas, la que tiene más votos incluye un fragmento de código de Python independiente para hacer lo que creo que está buscando.
doug

3
El término que estás buscando es Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet
Mark Ransom

Para una pregunta más general, con respuestas mucho mejores que aquí: stackoverflow.com/a/57197866/624066
MestreLion

Respuestas:


183

Utilice el operador de formato %:

>>> '#%02x%02x%02x' % (0, 128, 64)
'#008040'

Tenga en cuenta que no comprobará los límites ...

>>> '#%02x%02x%02x' % (0, -1, 9999)
'#00-1270f'

Sin embargo, ¿es realmente necesario el límite de 2 dígitos? Siempre que los valores RGB estén dentro de los límites adecuados de 0-255, no debería necesitarlo. Así que podrías hacerlo'#%x%x%x' % (r, g, b)
wordsforthewise

3
En realidad, ahora veo que si tiene un valor de 0, debe rellenarse con otro 0. Por lo tanto, el 02 para que sea de dos dígitos.
wordsforthewise

51
def clamp(x): 
  return max(0, min(x, 255))

"#{0:02x}{1:02x}{2:02x}".format(clamp(r), clamp(g), clamp(b))

Esto utiliza el método preferido de formateo de cadenas, como se describe en PEP 3101 . También utiliza min()y maxpara asegurarse de que 0 <= {r,g,b} <= 255.

La actualización agregó la función de abrazadera como se sugiere a continuación.

Actualización A partir del título de la pregunta y el contexto dado, debería ser obvio que esto espera 3 ints en [0,255] y siempre devolverá un color cuando se pasen 3 ints. Sin embargo, a partir de los comentarios, esto puede no ser obvio para todos, así que deje que se indique explícitamente:

Con tres intvalores, esto devolverá un triplete hexadecimal válido que representa un color. Si esos valores están entre [0,255], entonces los tratará como valores RGB y devolverá el color correspondiente a esos valores.


20

Esta es una pregunta antigua, pero para obtener información, desarrollé un paquete con algunas utilidades relacionadas con colores y mapas de color y contiene la función rgb2hex que buscaba para convertir triplete en valor hexa (que se puede encontrar en muchos otros paquetes, por ejemplo, matplotlib). Está en pypi

pip install colormap

y entonces

>>> from colormap import rgb2hex
>>> rgb2hex(0, 128, 64)
'##008040'

Se comprueba la validez de las entradas (los valores deben estar entre 0 y 255).


3
Intenté usar rgb2hex pero recibí un error "ImportError: No hay módulo llamado easydev.tools". ¿Puede sugerir alguna solución?
Abhils

Intente reinstalar easydev. Luego, 'pip3 install easydev'.
Shounak Ray

16

He creado un programa Python completo para él, las siguientes funciones pueden convertir rgb a hexadecimal y viceversa.

def rgb2hex(r,g,b):
    return "#{:02x}{:02x}{:02x}".format(r,g,b)

def hex2rgb(hexcode):
    return tuple(map(ord,hexcode[1:].decode('hex')))

Puede ver el código completo y el tutorial en el siguiente enlace: Conversión de RGB a Hex y de Hex a RGB usando Python


No funciona para el valor decimal de rgb. ¿Puedes sugerirme alguna solución?
Abhils

Redondo. No debería haber una gran diferencia en el color final.
Shounak Ray

9
triplet = (0, 128, 64)
print '#'+''.join(map(chr, triplet)).encode('hex')

o

from struct import pack
print '#'+pack("BBB",*triplet).encode('hex')

python3 es ligeramente diferente

from base64 import b16encode
print(b'#'+b16encode(bytes(triplet)))

3

Tenga en cuenta que esto solo funciona con python3.6 y superior.

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)}"

Lo anterior es equivalente a:

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

Esta función rgb2hex, aplicada a (13,13,12), da 0xDDC, pero el sitio web RGB to HEX lo da como 0x0D0D0C, y esto también coincide con la idea de que el número debería ser 13 * 65536 + 13 * 256 + 12, y Python lee 0xDDC como 3548.
Lars Ericson

Los colores CSS son inconsistentes. Hay colores hexadecimales de 6 dígitos, colores hexadecimales de 3 dígitos, notación rgb con decimales y porcentajes, hsl, etc. He modificado la fórmula para que siempre proporcione colores hexadecimales de 6 dígitos, y aunque creo que puede ser más consistente, No estoy seguro de que sea más correcto.
Brian Bruggeman

3

puede usar lambda y f-strings (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))

uso

rgb2hex(r,g,b) #output = #hexcolor hex2rgb("#hex") #output = (r,g,b) hexcolor must be in #hex format


1
No se recomienda llamar directamente a lambda por una serie de razones. Los usé así en un proyecto que fue revisado y todos dijeron lo mismo, no llamar directamente.
MikeyB

2
def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue)

background = RGB(0, 128, 64)

Sé que las frases ingeniosas en Python no son necesariamente vistas con amabilidad. Pero hay momentos en los que no puedo resistirme a aprovechar lo que permite el analizador de Python. Es la misma respuesta que la solución de Dietrich Epp (la mejor), pero envuelta en una función de una sola línea. ¡Gracias Dietrich!

Lo estoy usando ahora con tkinter :-)


2

Aquí hay una función más completa para manejar situaciones en las que puede tener valores RGB en el rango [0,1] o el rango [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))

1

En Python 3.6 , puede usar f-strings para hacer este limpiador:

rgb = (0,128, 64)
f'#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}'

Por supuesto, puede poner eso en una función y, como beneficio adicional, los valores se redondean y se convierten a int :

def rgb2hex(r,g,b):
    return f'#{int(round(r)):02x}{int(round(g)):02x}{int(round(b)):02x}'

rgb2hex(*rgb)

1

También puede usar operadores de bits que son bastante eficientes, aunque dudo que le preocupe la eficiencia con algo como esto. También es relativamente limpio. Tenga en cuenta que no sujeta ni comprueba los límites. Esto ha sido compatible desde al menos Python 2.7.17 .

hex(r << 16 | g << 8 | b)

Y para cambiarlo para que comience con un #, puede hacer:

"#" + hex(243 << 16 | 103 << 8 | 67)[2:]

1

Estoy realmente sorprendido de que nadie sugiera este enfoque:

Para Python 2 y 3:

'#' + ''.join('{:02X}'.format(i) for i in colortuple)

Python 3.6+:

'#' + ''.join(f'{i:02X}' for i in colortuple)

Como una función:

def hextriplet(colortuple):
    return '#' + ''.join(f'{i:02X}' for i in colortuple)

color = (0, 128, 64)
print(hextriplet(color))
#008040

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.