Mengonversi tupel warna RGB menjadi kode enam digit, dengan Python

93

Saya perlu mengubah (0, 128, 64) menjadi sesuatu seperti ini # 008040. Saya tidak yakin harus menyebut apa yang terakhir, membuat pencarian menjadi sulit.

persegi panjang
sumber
Lihat jawaban SO sebelumnya stackoverflow.com/questions/214359/… --dari tiga jawaban, satu dengan suara terbanyak menyertakan cuplikan kode python untuk melakukan apa yang saya yakin Anda cari.
Doug
3
Istilah yang Anda cari adalah Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet
Mark Ransom
Untuk pertanyaan yang lebih umum, dengan jawaban yang jauh lebih baik daripada di sini: stackoverflow.com/a/57197866/624066
MestreLion

Jawaban:

190

Gunakan operator format %:

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

Perhatikan bahwa itu tidak akan memeriksa batas ...

>>> '#%02x%02x%02x' % (0, -1, 9999)
'#00-1270f'
Dietrich Epp
sumber
Apakah batas 2 digit benar-benar diperlukan? Selama nilai RGB berada dalam batas yang benar antara 0-255, Anda seharusnya tidak membutuhkannya. Jadi Anda bisa melakukannya'#%x%x%x' % (r, g, b)
kata
3
Sebenarnya sekarang saya melihat bahwa jika Anda memiliki nilai 0, itu perlu diisi dengan 0. Jadi 02 untuk membuatnya menjadi dua digit.
kata
52
def clamp(x): 
  return max(0, min(x, 255))

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

Ini menggunakan metode pemformatan string yang disukai, seperti yang dijelaskan di PEP 3101 . Itu juga menggunakan min()dan maxuntuk memastikan itu 0 <= {r,g,b} <= 255.

Pembaruan menambahkan fungsi penjepit seperti yang disarankan di bawah ini.

Pembaruan Dari judul pertanyaan dan konteks yang diberikan, harus jelas bahwa ini mengharapkan 3 int dalam [0,255] dan akan selalu mengembalikan warna ketika melewati 3 int tersebut. Namun, dari komentar, ini mungkin tidak jelas bagi semua orang, jadi biarkan secara eksplisit dinyatakan:

Asalkan tiga intnilai, ini akan mengembalikan triplet hex valid yang mewakili warna. Jika nilai tersebut berada di antara [0,255], maka itu akan memperlakukannya sebagai nilai RGB dan mengembalikan warna yang sesuai dengan nilai tersebut.

Jesse Dhillon
sumber
20

Ini adalah pertanyaan lama tetapi untuk informasi, saya mengembangkan sebuah paket dengan beberapa utilitas yang berhubungan dengan warna dan colormaps dan berisi fungsi rgb2hex yang Anda cari untuk mengubah triplet menjadi nilai hexa (yang dapat ditemukan di banyak paket lain, misalnya matplotlib). Ada di pypi

pip install colormap

lalu

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

Validitas input diperiksa (nilai harus antara 0 dan 255).

Thomas Cokelaer
sumber
3
Saya mencoba menggunakan rgb2hex tetapi mendapat pesan kesalahan "ImportError: Tidak ada modul bernama easydev.tools". Bisakah Anda menyarankan solusi untuk itu?
Abhils
Coba instal ulang easydev. Kemudian 'pip3 install easydev'.
Shounak Ray
16

Saya telah membuat program python lengkap untuk itu fungsi berikut dapat mengubah rgb menjadi hex dan sebaliknya.

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

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

Anda dapat melihat kode lengkap dan tutorial di tautan berikut: Konversi RGB ke Hex dan Hex ke RGB menggunakan Python

Mohd Shibli
sumber
Ini tidak berfungsi untuk nilai desimal rgb. Bisakah Anda menyarankan saya solusi untuk itu?
Abhils
Bulat. Seharusnya tidak ada perbedaan besar pada warna akhir.
Shounak Ray
9
triplet = (0, 128, 64)
print '#'+''.join(map(chr, triplet)).encode('hex')

atau

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

python3 sedikit berbeda

from base64 import b16encode
print(b'#'+b16encode(bytes(triplet)))
John La Rooy
sumber
3

Berikut adalah fungsi yang lebih lengkap untuk menangani situasi di mana Anda mungkin memiliki nilai RGB dalam kisaran [0,1] atau kisaran [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))
Richard
sumber
Ini luar biasa! Fungsi yang benar-benar umum. Terima kasih, Richard!
Sunghee Yun
3

Perhatikan bahwa ini hanya berfungsi dengan python3.6 dan yang lebih baru.

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

Di atas sama dengan:

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
Brian Bruggeman
sumber
Fungsi rgb2hex ini, diterapkan ke (13,13,12), memberikan 0xDDC, tetapi situs web RGB ke HEX memberikannya sebagai 0x0D0D0C, dan ini juga sesuai dengan gagasan bahwa nomor tersebut harus 13 * 65536 + 13 * 256 + 12, dan 0xDDC dibaca oleh Python sebagai 3548.
Lars Ericson
Warna CSS tidak konsisten. Ada 6 digit warna hex, 3 digit warna hex, notasi rgb dengan desimal dan persentase, hsl, dll. Saya telah mengubah rumusnya untuk selalu memberikan 6 digit warna hex, dan meskipun menurut saya mungkin lebih konsisten, saya Saya tidak yakin itu lebih benar.
Brian Bruggeman
3

Anda dapat menggunakan lambda dan f-string (tersedia dalam 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))

pemakaian

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

Kaneki
sumber
1
Memanggil lambda secara langsung tidak disarankan karena sejumlah alasan. Saya menggunakannya seperti ini pada proyek yang ditinjau dan semua orang mengatakan hal yang sama, bukan untuk menelepon secara langsung.
MikeyB
2
def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue)

background = RGB(0, 128, 64)

Saya tahu one-liner dengan Python tidak selalu dipandang baik. Tetapi ada kalanya saya tidak bisa menahan diri untuk memanfaatkan apa yang diizinkan oleh parser Python. Ini jawaban yang sama dengan solusi Dietrich Epp (yang terbaik), tetapi dibungkus dalam satu fungsi baris. Jadi, terima kasih Dietrich!

Saya menggunakannya sekarang dengan tkinter :-)

MikeyB
sumber
1

Di Python 3.6 , Anda dapat menggunakan f-string untuk membuat ini lebih bersih:

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

Tentu saja Anda dapat memasukkannya ke dalam sebuah fungsi , dan sebagai bonus, nilai dibulatkan dan diubah menjadi int :

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

rgb2hex(*rgb)
toto_tico
sumber
1

Anda juga dapat menggunakan operator yang sedikit bijak yang cukup efisien, meskipun saya ragu Anda akan khawatir tentang efisiensi dengan sesuatu seperti ini. Itu juga relatif bersih. Perhatikan itu tidak menjepit atau memeriksa batas. Ini telah didukung setidaknya sejak Python 2.7.17 .

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

Dan untuk mengubahnya sehingga dimulai dengan # yang dapat Anda lakukan:

"#" + hex(243 << 16 | 103 << 8 | 67)[2:]
Quokka tanpa henti
sumber
1

Saya benar-benar terkejut tidak ada yang menyarankan pendekatan ini:

Untuk Python 2 dan 3:

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

Python 3.6+:

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

Sebagai fungsi:

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

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