RGB Int to RGB - Python
How can I convert an RGB integer to the corresponding RGB tuple (R,G,B)
? Seems simple enough, but I can't find anything on google.
I know that for every RGB (r,g,b)
you have the integer n = r256^2 + g256 + b
, how can I solve the reverse in Python, IE given an n
, I need the r
,g
,b
values.
I'm not a Python expert by all means, but as far as I know it has the same operators as C.
If so this should work and it should also be a lot quicker than using modulo and division.
Blue = RGBint & 255
Green = (RGBint >> 8) & 255
Red = (RGBint >> 16) & 255
What it does it to mask out the lowest byte in each case (the binary and with 255.. Equals to a 8 one bits). For the green and red component it does the same, but shifts the color-channel into the lowest byte first.
From a RGB integer:
Blue = RGBint mod 256
Green = RGBint / 256 mod 256
Red = RGBint / 256 / 256 mod 256
This can be pretty simply implemented once you know how to get it. :)
Upd: Added python function. Not sure if there's a better way to do it, but this works on Python 3 and 2.4
def rgb_int2tuple(rgbint):
return (rgbint // 256 // 256 % 256, rgbint // 256 % 256, rgbint % 256)
There's also an excellent solution that uses bitshifting and masking that's no doubt much faster that Nils Pipenbrinck posted.
>>> import struct
>>> str='aabbcc'
>>> struct.unpack('BBB',str.decode('hex'))
(170, 187, 204)
for python3:
>>> struct.unpack('BBB', bytes.fromhex(str))
and
>>> rgb = (50,100,150)
>>> struct.pack('BBB',*rgb).encode('hex')
'326496'
for python3:
>>> bytes.hex(struct.pack('BBB',*rgb))
>>> r, g, b = (111, 121, 131)
>>> packed = int('%02x%02x%02x' % (r, g, b), 16)
This produces the following integer:
>>> packed
7305603
You can then unpack it either the long explicit way:
>>> packed % 256
255
>>> (packed / 256) % 256
131
>>> (packed / 256 / 256) % 256
121
>>> (packed / 256 / 256 / 256) % 256
111
..or in a more compact manner:
>>> b, g, r = [(packed >> (8*i)) & 255 for i in range(3)]
>>> r, g, b
Sample applies with any number of digits, e.g an RGBA colour:
>>> packed = int('%02x%02x%02x%02x' % (111, 121, 131, 141), 16)
>>> [(packed >> (8*i)) & 255 for i in range(4)]
[141, 131, 121, 111]
I assume you have a 32-bit integer containing the RGB values (e.g. ARGB). Then you can unpack the binary data using the struct
module:
# 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)