Konvertieren eines RGB-Farbtupels in einen sechsstelligen Code in Python

87

Ich muss (0, 128, 64) in so etwas wie # 008040 konvertieren. Ich bin mir nicht sicher, wie ich letzteres nennen soll, was die Suche schwierig macht.

Rechteck
quelle
Siehe vorherige SO-Antwort stackoverflow.com/questions/214359/… - Von den drei Antworten enthält die mit den meisten Stimmen ein Python-Code-Snippet, mit dem Sie das tun können, wonach Sie suchen.
Doug
3
Der Begriff, den Sie suchen, ist Hex Triplet. en.wikipedia.org/wiki/Hex_color#Hex_triplet
Mark Ransom
Für eine allgemeinere Frage mit viel besseren Antworten als hier: stackoverflow.com/a/57197866/624066
MestreLion

Antworten:

183

Verwenden Sie den Formatoperator %:

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

Beachten Sie, dass keine Grenzen überprüft werden ...

>>> '#%02x%02x%02x' % (0, -1, 9999)
'#00-1270f'
Dietrich Epp
quelle
Ist das zweistellige Limit wirklich notwendig? Solange die RGB-Werte innerhalb der richtigen Grenzen von 0 bis 255 liegen, sollten Sie sie nicht benötigen. Sie könnten es also einfach tun'#%x%x%x' % (r, g, b)
Worte für den
3
Eigentlich sehe ich jetzt, dass wenn Sie einen Wert von 0 haben, dieser mit einer weiteren 0 aufgefüllt werden muss. Also die 02, um sie zweistellig zu machen.
Worte für den
51
def clamp(x): 
  return max(0, min(x, 255))

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

Dies verwendet die bevorzugte Methode zur Formatierung von Zeichenfolgen, wie in PEP 3101 beschrieben . Es verwendet auch min()und maxum dies sicherzustellen 0 <= {r,g,b} <= 255.

Update hat die Klemmfunktion wie unten vorgeschlagen hinzugefügt.

Aktualisierung Aus dem Titel der Frage und dem angegebenen Kontext sollte ersichtlich sein, dass dies 3 Ints in [0,255] erwartet und immer eine Farbe zurückgibt, wenn 3 solcher Ints übergeben werden. Aus den Kommentaren geht jedoch hervor, dass dies möglicherweise nicht für alle offensichtlich ist. Lassen Sie es daher ausdrücklich sagen:

Wenn drei intWerte angegeben werden, wird ein gültiges Hex-Triplett zurückgegeben, das eine Farbe darstellt. Wenn diese Werte zwischen [0,255] liegen, werden diese als RGB-Werte behandelt und die diesen Werten entsprechende Farbe zurückgegeben.

Jesse Dhillon
quelle
20

Dies ist eine alte Frage, aber zur Information habe ich ein Paket mit einigen Dienstprogrammen für Farben und Farbkarten entwickelt, das die Funktion rgb2hex enthält, mit der Sie Triplett in Hexa-Werte konvertieren wollten (die in vielen anderen Paketen enthalten ist, z. B. matplotlib). Es ist auf Pypi

pip install colormap

und dann

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

Die Gültigkeit der Eingänge wird überprüft (Werte müssen zwischen 0 und 255 liegen).

Thomas Cokelaer
quelle
3
Ich habe versucht, rgb2hex zu verwenden, habe aber die Fehlermeldung "ImportError: Kein Modul namens easydev.tools" erhalten. Können Sie eine Lösung dafür vorschlagen?
Abhils
Versuchen Sie, easydev neu zu installieren. Dann 'pip3 install easydev'.
Shounak Ray
16

Ich habe ein vollständiges Python-Programm dafür erstellt. Die folgenden Funktionen können RGB in Hex konvertieren und umgekehrt.

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

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

Den vollständigen Code und das Tutorial finden Sie unter folgendem Link: Konvertierung von RGB in Hex und Hex in RGB mit Python

Mohd Shibli
quelle
Es funktioniert nicht für den Dezimalwert von rgb. Können Sie mir eine Lösung dafür vorschlagen?
Abhils
Runden. Es sollte keinen großen Unterschied in der endgültigen Farbe geben.
Shounak Ray
9
triplet = (0, 128, 64)
print '#'+''.join(map(chr, triplet)).encode('hex')

oder

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

python3 ist etwas anders

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

Beachten Sie, dass dies nur mit Python3.6 und höher funktioniert.

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

Das Obige ist das Äquivalent von:

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
quelle
Diese Funktion rgb2hex, die auf (13,13,12) angewendet wird, gibt 0xDDC an, aber die Website RGB to HEX gibt sie als 0x0D0D0C an, und dies stimmt auch mit der Idee überein, dass die Zahl 13 * 65536 + 13 * 256 + 12 sein sollte. und 0xDDC wird von Python als 3548 gelesen.
Lars Ericson
CSS-Farben sind inkonsistent. Es gibt 6-stellige Hex-Farben, 3-stellige Hex-Farben, RGB-Notation mit Dezimalstellen und Prozentsätzen, hsl usw. Ich habe die Formel so angepasst, dass sie immer 6-stellige Hex-Farben liefert, und obwohl ich denke, dass sie konsistenter ist, habe ich Ich bin mir nicht sicher, ob es korrekter ist.
Brian Bruggeman
3

Sie können Lambda und F-Strings verwenden (verfügbar in 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))

Verwendung

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

Kaneki
quelle
1
Ein direkter Anruf bei Lambda wird aus verschiedenen Gründen nicht empfohlen. Ich habe sie so für ein Projekt verwendet, das überprüft wurde, und alle sagten dasselbe, nicht direkt anzurufen.
MikeyB
2
def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue)

background = RGB(0, 128, 64)

Ich weiß, dass Einzeiler in Python nicht unbedingt freundlich betrachtet werden. Aber es gibt Zeiten, in denen ich nicht widerstehen kann, die Vorteile des Python-Parsers zu nutzen. Es ist die gleiche Antwort wie Dietrich Epps Lösung (die beste), aber in einer einzigen Zeilenfunktion zusammengefasst. Also, danke Dietrich!

Ich benutze es jetzt mit tkinter :-)

MikeyB
quelle
2

Hier finden Sie eine umfassendere Funktion für die Behandlung von Situationen, in denen RGB-Werte im Bereich [0,1] oder im Bereich [0,255] liegen können .

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
quelle
1

In Python 3.6 können Sie F-Strings verwenden , um dies sauberer zu machen:

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

Natürlich können Sie das in eine Funktion einfügen , und als Bonus werden Werte gerundet und in int konvertiert :

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

rgb2hex(*rgb)
toto_tico
quelle
1

Sie können auch bitweise Operatoren verwenden, was ziemlich effizient ist, obwohl ich bezweifle, dass Sie sich bei so etwas Sorgen um die Effizienz machen würden. Es ist auch relativ sauber. Beachten Sie, dass die Grenzen nicht geklemmt oder überprüft werden. Dies wird seit mindestens Python 2.7.17 unterstützt .

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

Und um es so zu ändern, dass es mit einem # beginnt, können Sie Folgendes tun:

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

Ich bin wirklich überrascht, dass niemand diesen Ansatz vorgeschlagen hat:

Für Python 2 und 3:

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

Python 3.6+:

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

Als eine Funktion:

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

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