RGB Int в RGB - Python - PullRequest
       11

RGB Int в RGB - Python

17 голосов
/ 14 февраля 2010

Как преобразовать целое число RGB в соответствующий кортеж RGB (R,G,B)? Кажется достаточно простым, но я ничего не могу найти в Google.

Я знаю, что для каждого RGB (r,g,b) у вас есть целое число n = r256^2 + g256 + b, как я могу решить обратное в Python, IE дает n, мне нужны r, g, b значения.

Ответы [ 10 ]

43 голосов
/ 14 февраля 2010

Я ни в коем случае не эксперт по Python, но, насколько я знаю, у него те же операторы, что и у C.

Если это так, это должно работать, и это также должно быть намного быстрее, чем по модулю и делению.

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

Что он делает, чтобы замаскировать младший байт в каждом случае (двоичный и с 255 ... равно 8 одним битам). Для зеленого и красного компонента он делает то же самое, но сначала смещает цветовой канал в младший байт.

14 голосов
/ 14 февраля 2010

Из целого числа RGB:

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

Это может быть довольно просто реализовано, если вы знаете, как его получить. :)

Upd: добавлена ​​функция Python. Не уверен, что есть лучший способ сделать это, но это работает на Python 3 и 2.4

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

Существует также отличное решение, использующее битовую сдвиг и маскировку, которое, без сомнения, намного быстрее, чем написал Нильс Пипенбринк.

9 голосов
/ 28 ноября 2010
>>> import struct
>>> str='aabbcc'
>>> struct.unpack('BBB',str.decode('hex'))
(170, 187, 204)

for python3:
>>> struct.unpack('BBB', bytes.fromhex(str))

и

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

for python3:
>>> bytes.hex(struct.pack('BBB',*rgb))
6 голосов
/ 01 декабря 2011
>>> r, g, b = (111, 121, 131)
>>> packed = int('%02x%02x%02x' % (r, g, b), 16)

Получает следующее целое число:

>>> packed
7305603

Затем вы можете распаковать его длинным явным способом:

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

.. или более компактно:

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

Образец применяется с любым количеством цифр, например, цвет 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]
6 голосов
/ 14 февраля 2010

Я предполагаю, что у вас есть 32-разрядное целое число, содержащее значения RGB (например, ARGB). Затем вы можете распаковать двоичные данные, используя модуль 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)
3 голосов
/ 04 сентября 2013

Просто замечание для тех, кто использует Google Appengine Images Python API. Я обнаружил, что у меня была ситуация, когда мне нужно было предоставить метод с 32-битным значением цвета RGB.

В частности, если вы используете API для преобразования PNG (или любого изображения с прозрачными пикселями), вам необходимо предоставить методу execute_transforms аргумент с именем transparent_substitution_rgb, который должен быть 32-битным значением цвета RGB .

Заимствуя из ответа dbr, я придумал метод, подобный этому:

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))
2 голосов
/ 03 марта 2010
def unpack2rgb(intcol):
    tmp, blue= divmod(intcol, 256)
    tmp, green= divmod(tmp, 256)
    alpha, red= divmod(tmp, 256)
    return alpha, red, green, blue

Если бы было принято только предложение divmod(value, (divider1, divider2, divider3…)), это также упростило бы различные преобразования времени.

0 голосов
/ 09 октября 2015

Добавление к тому, что упомянуто выше. Краткая однострочная альтернатива.

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

И чтобы избежать путаницы в будущем.

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)
0 голосов
/ 28 июля 2015

Если вы используете NumPy и у вас есть массив RGBints, вы также можете просто изменить его dtype, чтобы извлечь красный, зеленый, синий и альфа-компоненты:

>>> 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')
0 голосов
/ 14 февраля 2010

Вероятно, есть более короткий способ сделать это:

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

РЕДАКТИРОВАТЬ: это неправильно - дает ответ в шестнадцатеричном, OP хотел Int. РЕДАКТИРОВАТЬ 2: улучшен, чтобы уменьшить страдания и неудачи - необходим «% 06x», чтобы гекс всегда отображался в виде шести цифр [благодаря комментарию Питера Хансена].

...