RGB Int a RGB – Python

¿Cómo puedo convertir un entero RGB a la tupla RGB correspondiente (R,G,B) ? Parece bastante simple, pero no puedo encontrar nada en google.

Sé que para cada RGB (r,g,b) tienes el número entero n = r256^2 + g256 + b , ¿cómo puedo resolver el reverso en Python? IE, dada una n , necesito los valores de r , g , b .

No soy un experto en Python por todos los medios, pero por lo que sé, tiene los mismos operadores que C.

Si es así, esto debería funcionar y también debería ser mucho más rápido que usar el módulo y la división.

 Blue = RGBint & 255 Green = (RGBint >> 8) & 255 Red = (RGBint >> 16) & 255 

Lo que hace es enmascarar el byte más bajo en cada caso (el binario y con 255 .. Es igual a 8 bits de uno). Para el componente verde y rojo hace lo mismo, pero primero cambia el canal de color al byte más bajo.

De un entero RGB:

 Blue = RGBint mod 256 Green = RGBint / 256 mod 256 Red = RGBint / 256 / 256 mod 256 

Esto puede implementarse de manera bastante simple una vez que sepa cómo obtenerlo. 🙂

Actualizaciones: Añadida la función python. No estoy seguro de si hay una mejor manera de hacerlo, pero esto funciona en Python 3 y 2.4

 def rgb_int2tuple(rgbint): return (rgbint // 256 // 256 % 256, rgbint // 256 % 256, rgbint % 256) 

También hay una excelente solución que utiliza el cambio de bits y el enmascaramiento que, sin duda, es mucho más rápido que Nils Pipenbrinck publicó.

 >>> import struct >>> str='aabbcc' >>> struct.unpack('BBB',str.decode('hex')) (170, 187, 204) for python3: >>> struct.unpack('BBB', bytes.fromhex(str)) 

y

 >>> rgb = (50,100,150) >>> struct.pack('BBB',*rgb).encode('hex') '326496' for python3: >>> bytes.hex(struct.pack('BBB',*rgb)) 

Supongo que tiene un entero de 32 bits que contiene los valores RGB (por ejemplo, ARGB). Luego, puede descomprimir los datos binarios utilizando el módulo struct :

 # Create an example value (this represents your 32-bit input integer in this example). # The following line results in exampleRgbValue = binary 0x00FF77F0 (big endian) exampleRgbValue = struct.pack(">I", 0x00FF77F0) # Unpack the value (result is: a = 0, r = 255, g = 119, b = 240) a, r, g, b = struct.unpack("BBBB", exampleRgbValue) 
 >>> r, g, b = (111, 121, 131) >>> packed = int('%02x%02x%02x' % (r, g, b), 16) 

Esto produce el siguiente entero:

 >>> packed 7305603 

A continuación, puede descomprimirlo de la manera explícita larga:

 >>> packed % 256 255 >>> (packed / 256) % 256 131 >>> (packed / 256 / 256) % 256 121 >>> (packed / 256 / 256 / 256) % 256 111 

..o de una manera más compacta:

 >>> b, g, r = [(packed >> (8*i)) & 255 for i in range(3)] >>> r, g, b 

La muestra se aplica con cualquier número de dígitos, por ejemplo, un color RGBA:

 >>> packed = int('%02x%02x%02x%02x' % (111, 121, 131, 141), 16) >>> [(packed >> (8*i)) & 255 for i in range(4)] [141, 131, 121, 111] 

Solo una nota para cualquiera que use la API de Google Appengine Images Python. Descubrí que tenía una situación en la que tenía que proporcionar un método con un valor de color RGB de 32 bits.

Específicamente, si está utilizando la API para convertir un PNG (o cualquier imagen con píxeles transparentes), deberá proporcionar al método execute_transforms un argumento llamado transparent_substitution_rgb que debe ser un valor de color RGB de 32 bits.

Tomando prestado de la respuesta de dbr, se me ocurrió un método similar a este:

 def RGBTo32bitInt(r, g, b): return int('%02x%02x%02x' % (r, g, b), 16) transformed_image = image.execute_transforms(output_encoding=images.JPEG, transparent_substitution_rgb=RGBTo32bitInt(255, 127, 0)) 
 def unpack2rgb(intcol): tmp, blue= divmod(intcol, 256) tmp, green= divmod(tmp, 256) alpha, red= divmod(tmp, 256) return alpha, red, green, blue 

Si solo se divmod(value, (divider1, divider2, divider3…)) la divmod(value, (divider1, divider2, divider3…)) , también se habrían simplificado varias conversiones de tiempo.

Probablemente hay una forma más corta de hacer esto:

 dec=10490586 hex="%06x" % dec r=hex[:2] g=hex[2:4] b=hex[4:6] rgb=(r,g,b) 

EDIT: esto es incorrecto, da la respuesta en Hex, OP wanted int. EDIT2: refinado para reducir la miseria y el fracaso: se necesita ‘% 06x’ para garantizar que el hex se muestre siempre con seis dígitos [gracias al comentario de Peter Hansen].

Si está utilizando NumPy y tiene una matriz de RGBints, también puede cambiar su tipo de dty para extraer los componentes rojo, verde, azul y alfa:

 >>> type(rgbints) numpy.ndarray >>> rgbints.shape (1024L, 768L) >>> rgbints.dtype dtype('int32') >>> rgbints.dtype = dtype('4uint8') >>> rgbints.shape (1024L, 768L, 4L) >>> rgbints.dtype dtype('uint8') 

Agregando a lo que se menciona arriba. Una alternativa concisa de una sola línea.

 # 2003199 or #E190FF is Dodger Blue. tuple((2003199 >> Val) & 255 for Val in (16, 8, 0)) # (30, 144, 255) 

Y para evitar cualquier confusión en el futuro.

 from collections import namedtuple RGB = namedtuple('RGB', ('Red', 'Green', 'Blue')) rgb_integer = 16766720 # Or #ffd700 is Gold. # The unpacking asterisk prevents a TypeError caused by missing arguments. RGB(*((rgb_integer >> Val) & 255 for Val in (16, 8, 0))) # RGB(Red=255, Green=215, Blue=0)