2010-02-14 32 views
14

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

sé que por cada RGB (r,g,b) usted tiene el número entero n = r256^2 + g256 + b, ¿cómo puedo resolver el inverso en Python, es decir, considerando un n, necesito los r, g, b valores.

+0

¿Qué quiere decir con RGB entero? –

+1

http://www.shodor.org/stella2java/rgbint.html, simplemente la fórmula que acabo de editar en la pregunta. '(255, 255, 255)' = '16777215' – Omar

Respuesta

37

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

Si lo que este debe trabajar y también debe ser mucho más rápido que el uso de módulo y división.

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

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

+1

+1, sin embargo, la ventaja de velocidad sobre una solución que usa% y // debe ser mínima. Ciertamente, mucho más rápido que las soluciones con llamadas a funciones (divmod, struct. [Un] pack, etc.). –

14

Desde un número entero RGB:

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

Esto se puede implementar bastante simple una vez que sabes cómo conseguirlo. :)

Upd: Se agregó la función de python. No estoy seguro 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) 

Hay también una excelente solución que utiliza bitshifting y enmascaramiento que es, sin duda, mucho más rápido que Nils Pipenbrinck publicada.

+2

No se olvide de usar la división de enteros y no la división de flotación. –

+0

A pesar de que usa división y módulo enteros, no creo que mi respuesta merezca una reducción. – Xorlev

+0

No, no merece un voto negativo. La gente no ha leído la información sobre herramientas del downvote-arrow y cree que el downvoting significa "no me gusta esto". – tzot

0

Probablemente hay un camino más corto para hacer esto:

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

EDIT: esto está mal - da la respuesta en Hex, OP quería int. EDIT2: refinado para reducir la miseria y el fracaso: se necesita '% 06x' para garantizar que el hexágono siempre se muestre como seis dígitos [gracias al comentario de Peter Hansen].

+1

Esto también fallará miserablemente si la cadena hexadecimal no tiene los seis dígitos esperados. Use "% 06x" para evitar eso. –

6

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

varias conversiones
# 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) 
+0

y sería increíblemente lento (2 llamadas a funciones) en comparación con otras soluciones –

+0

Puede que no sea la más práctica, pero es una solución genial. – Rich

2
def unpack2rgb(intcol): 
    tmp, blue= divmod(intcol, 256) 
    tmp, green= divmod(tmp, 256) 
    alpha, red= divmod(tmp, 256) 
    return alpha, red, green, blue 

Si sólo la sugerencia divmod(value, (divider1, divider2, divider3…)) fue aceptado, habría simplificado de tiempo también.

9
>>> 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)) 
5
>>> r, g, b = (111, 121, 131) 
>>> packed = int('%02x%02x%02x' % (r, g, b), 16) 

Esto produce el siguiente número entero:

>>> packed 
7305603 

A continuación, puede descomprimirlo ya sea el camino más largo explícita:

>>> 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] 
3

Sólo una nota para cualquier persona que utilice la API de imágenes de Python de App Engine de Google. 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á suministrar el método execute_transforms con un argumento llamado transparent_substitution_rgb que tiene que ser un color RGB de 32 bits valor.

Los préstamos de la respuesta de DBR, se me ocurrió con 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)) 
-1

Si está utilizando NumPy y tiene una matriz de RGBints, también puede simplemente cambiar su dtype para extraer el rojo , verde, azul y componentes 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') 
-1

Agregando a lo que se ha mencionado anteriormente. Una alternativa concisa de una 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)