Python'da RGB renk grubunu altı basamaklı bir koda dönüştürme


93

(0, 128, 64) 'ü # 008040 gibi bir şeye dönüştürmem gerekiyor. İkincisine ne diyeceğimi bilmiyorum, bu da aramayı zorlaştırıyor.


Önceki SO cevabına bakın stackoverflow.com/questions/214359/… - üç cevabın en çok oyuna sahip olanı, peşinde olduğunuzu düşündüğüm şeyi yapmak için sabit bir python kod parçası içerir.
doug

3
Aradığınız terim Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet
Mark Ransom

Buradan çok daha iyi yanıtlarla daha genel bir soru için: stackoverflow.com/a/57197866/624066
MestreLion

Yanıtlar:


191

Biçim operatörünü kullanın %:

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

Sınırları kontrol etmeyeceğini unutmayın ...

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

2 basamaklı sınır gerçekten gerekli mi? RGB değerleri 0-255 arasında uygun sınırlarda olduğu sürece buna ihtiyacınız olmamalıdır. Yani yapabilirsin'#%x%x%x' % (r, g, b)
wordforthewise

3
Aslında şimdi, eğer 0 değerine sahipseniz, başka bir 0 ile doldurulması gerektiğini görüyorum. Bu yüzden 02, iki basamaklı olsun.
wordsforthewise

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

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

Bu, PEP 3101'de açıklandığı gibi tercih edilen dizi formatlama yöntemini kullanır . Ayrıca kullandığı min()ve maxtemin etmek 0 <= {r,g,b} <= 255.

Güncelleme , aşağıda önerildiği gibi kelepçe işlevini ekledi.

Güncelleme Sorunun başlığından ve verilen bağlamdan, bunun [0,255] 'de 3 ints beklediği ve böyle 3 inte geçtiğinde her zaman bir renk geri döneceği açık olmalıdır. Bununla birlikte, yorumlardan, bu herkes için açık olmayabilir, bu yüzden açıkça ifade edilmesine izin verin:

Üç intdeğer sağlandığında , bu, bir rengi temsil eden geçerli bir onaltılık üçlü döndürecektir. Bu değerler [0,255] arasındaysa, bunları RGB değerleri olarak değerlendirecek ve bu değerlere karşılık gelen rengi döndürecektir.


20

Bu eski bir sorudur, ancak bilgi için, renkler ve renk haritaları ile ilgili bazı yardımcı programlara sahip bir paket geliştirdim ve tripleti hexa değerine dönüştürmek istediğiniz rgb2hex işlevini (matplotlib gibi diğer birçok pakette bulunabilir) içerir. Pypi'de

pip install colormap

ve sonra

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

Girişlerin geçerliliği kontrol edilir (değerler 0 ile 255 arasında olmalıdır).


3
Rgb2hex'i kullanmayı denedim ancak "ImportError: easydev.tools adında modül yok" hatası aldım. Buna herhangi bir çözüm önerebilir misiniz?
Abhils

Easydev'i yeniden yüklemeyi deneyin. Ardından 'pip3 easydev'i kurun'.
Shounak Ray

16

Bunun için tam bir python programı oluşturdum, aşağıdaki işlevler rgb'yi hex'e dönüştürebilir ve bunun tersi de geçerlidir.

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

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

Kodun tamamını ve öğreticiyi aşağıdaki bağlantıda görebilirsiniz: RGB'den Hex'e ve Hex'ten RGB'ye Python kullanarak dönüştürme


Rgb'nin ondalık değeri için çalışmaz. Bana bunun için herhangi bir çözüm önerebilir misin?
Abhils

Yuvarlak. Son renkte çok büyük bir fark olmamalı.
Shounak Ray

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

veya

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

python3 biraz farklıdır

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

3

Burada, [0,1] aralığında veya [0,255] aralığında RGB değerlerine sahip olabileceğiniz durumların ele alınması için daha eksiksiz bir işlev verilmiştir .

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

Bu harika! Gerçekten genel işlev. Teşekkürler Richard!
Sunghee Yun

3

Bunun yalnızca python3.6 ve üstü ile çalıştığını unutmayın.

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

Yukarıdakiler şuna eşdeğerdir:

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

(13,13,12) 'ye uygulanan bu rgb2hex işlevi, 0xDDC verir, ancak RGB'den HEX'e web sitesi bunu 0x0D0D0C olarak verir ve bu, sayının 13 * 65536 + 13 * 256 + 12 olması gerektiği fikrine de uygundur, ve 0xDDC, Python tarafından 3548 olarak okunur.
Lars Ericson

CSS Renkleri tutarsız. 6 basamaklı onaltılık renkler, 3 basamaklı onaltılık renkler, ondalıklı ve yüzdeli rgb gösterimi, hsl, vb. Formülü her zaman 6 basamaklı onaltılık renk sağlayacak şekilde değiştirdim ve daha tutarlı olabileceğini düşünmeme rağmen, ben Daha doğru olduğundan emin değilim.
Brian Bruggeman

3

lambda ve f dizelerini kullanabilirsiniz (python 3.6+ sürümünde mevcuttur)

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

kullanım

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


1
Lambda'nın doğrudan çağrılması birçok nedenden ötürü önerilmez. Onları gözden geçirilmiş bir projede bu şekilde kullandım ve herkes aynı şeyi söyledi, doğrudan aramamaları için.
MikeyB

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

background = RGB(0, 128, 64)

Python'daki tek satırlıklara ille de nazik bakılmadığını biliyorum. Ancak Python ayrıştırıcısının izin verdiği şeyden yararlanmaya karşı koyamadığım zamanlar var. Dietrich Epp'in çözümüyle aynı cevap (en iyisi), ancak tek satırlık bir işleve bağlı. Öyleyse, teşekkürler Dietrich!

Şimdi tkinter ile kullanıyorum :-)


1

In Python 3.6 , kullanabileceğiniz f-dizeleri bu temiz hale getirme:

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

Elbette bunu bir işleve koyabilirsiniz ve bonus olarak değerler yuvarlanır ve int'e dönüştürülür :

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

rgb2hex(*rgb)

1

Bunun gibi bir şeyle verimlilik konusunda endişeleneceğinizden şüphe duysam da oldukça verimli olan biraz akıllı operatörler de kullanabilirsiniz. Aynı zamanda nispeten temiz. Sınırları sıkıştırmadığını veya kontrol etmediğini unutmayın. Bu, en az Python 2.7.17'den beri desteklenmektedir .

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

Ve bunu bir # ile başlayacak şekilde değiştirmek için şunları yapabilirsiniz:

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

1

Kimsenin bu yaklaşımı önermediğine gerçekten şaşırdım:

Python 2 ve 3 için:

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

Python 3.6+:

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

İşlev olarak:

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

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.