Перетворення набору кольорів RGB у шестизначний код на Python


87

Мені потрібно перетворити (0, 128, 64) на щось подібне # 008040. Я не знаю, як назвати останнє, ускладнюючи пошук.


Див перед SO відповідь stackoverflow.com/questions/214359 / ... --of трьох відповідей, один з більшістю голосів включає в себе стоячі уздовж пітона фрагмент коду , щоб зробити те , що я вважаю , що ви після цього .
дуг

3
Ви шукаєте термін Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet
Марк Ренсом

Для більш загального питання, з набагато краще , ніж відповідей тут: stackoverflow.com/a/57197866/624066
MestreLion

Відповіді:


183

Використовуйте оператор форматування %:

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

Зверніть увагу, що це не перевірить межі ...

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

Чи дійсно необхідний двозначний ліміт? Поки значення RGB знаходяться в належних межах 0-255, це вам не потрібно. Отже, ви могли просто зробити'#%x%x%x' % (r, g, b)
слова, наприклад,

3
Насправді я бачу, що якщо у вас є значення 0, його потрібно додати ще на 0. Таким чином, 02, щоб це було двозначним числом.
слованаприклад

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

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

Тут використовується кращий метод форматування рядків, як описано в PEP 3101 . Він також використовує min()і maxдля того, щоб 0 <= {r,g,b} <= 255.

Оновлення додало функцію затискача, як запропоновано нижче.

Оновлення З назви запитання та поданого контексту має бути очевидним, що це передбачає 3 ints в [0,255] і завжди поверне колір, коли передано 3 таких ints. Однак із коментарів це може бути не очевидним для всіх, тож нехай буде прямо зазначено:

За умови трьох intзначень це поверне дійсний шістнадцятковий триплет, що представляє колір. Якщо ці значення знаходяться в межах [0,255], тоді вони розглядатимуть їх як значення RGB і повертатимуть колір, що відповідає цим значенням.


20

Це старе питання, але для інформації я розробив пакет з деякими утилітами, пов’язаними з кольорами та кольоровими картами, і містить функцію rgb2hex, яку ви хотіли перетворити триплет у значення hexa (яке можна знайти у багатьох інших пакетах, наприклад, matplotlib). Це на pypi

pip install colormap

і потім

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

Перевіряється дійсність входів (значення повинні бути від 0 до 255).


3
Я спробував використати rgb2hex, але отримав помилку "ImportError: Немає модуля з іменем easydev.tools". Чи можете ви запропонувати якесь рішення?
Абхілс,

Спробуйте переінсталювати easydev. Потім 'pip3 встановити easydev'.
Шунак Рей

16

Я створив для нього повну програму python, наступні функції можуть перетворювати rgb в hex і навпаки.

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

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

Ви можете переглянути повний код та підручник за таким посиланням: RGB в Hex та Hex в RGB перетворення за допомогою Python


Це не працює для десяткового значення rgb. Чи можете ви запропонувати мені якесь рішення?
Абхілс

Круглі. У кінцевому кольорі не повинно бути величезної різниці.
Shounak Ray

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

або

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

python3 дещо відрізняється

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

3

Зверніть увагу, що це працює лише з python3.6 і вище.

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

Вищезазначене є еквівалентом:

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

Ця функція rgb2hex, застосована до (13,13,12), дає 0xDDC, але веб-сайт RGB до HEX надає її як 0x0D0D0C, і це також узгоджується з ідеєю, що число має бути 13 * 65536 + 13 * 256 + 12, і 0xDDC читається Python як 3548.
Ларс Еріксон,

Кольори CSS суперечливі. Існують 6-значні шістнадцяткові кольори, 3-значні шістнадцяткові кольори, позначення rgb з десятковими і відсотками, hsl і т. Д. Я доопрацював формулу, щоб завжди надавати 6-значні шістнадцяткові кольори, і хоча я думаю, що це може бути більш послідовно, я Не впевнений, що це правильніше.
Брайан Брюггеман,

3

ви можете використовувати лямбда і f-рядки (доступно в 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))

використання

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


1
Не рекомендується дзвонити лямбда безпосередньо з багатьох причин. Я використовував їх так у проекті, який переглядався, і всі говорили одне і те ж, а не телефонувати безпосередньо.
MikeyB

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

background = RGB(0, 128, 64)

Я знаю, що на однокласники в Python не обов'язково ставляться доброзичливо. Але бувають випадки, коли я не можу не встояти, скориставшись тим, що дозволяє аналізатор Python. Це та сама відповідь, що і рішення Дітріха Еппа (найкраще), але в єдиному рядку. Отже, дякую Дітріху!

Я використовую його зараз з tkinter :-)


2

Ось більш повна функція для обробки ситуацій, коли у вас можуть бути значення RGB у діапазоні [0,1] або діапазоні [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

У Python 3.6 ви можете використовувати f-рядки, щоб зробити це чистішим:

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

Звичайно, ви можете ввести це у функцію , і як бонус, значення округлюються і перетворюються на int :

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

rgb2hex(*rgb)

1

Ви також можете використовувати трохи мудрі оператори, що є досить ефективним, хоча я сумніваюся, що ви б турбувались про ефективність з чимось подібним. Це також відносно чисто. Зверніть увагу, що він не затискає і не перевіряє межі. Це підтримується принаймні з Python 2.7.17 .

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

І змінити його так, щоб він починався з #, ви можете зробити:

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

1

Я щиро здивований, що ніхто не пропонував такий підхід:

Для Python 2 і 3:

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

Python 3.6+:

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

Як функція:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.