2010-02-14 16 views
14

Wie kann ich eine RGB-Ganzzahl in das entsprechende RGB-Tupel (R,G,B) konvertieren? Scheint einfach genug, aber ich kann nichts bei Google finden.RGB Int in RGB - Python

Ich weiß, dass (r,g,b) für jede RGB haben Sie die ganze Zahl n = r256^2 + g256 + b, wie kann ich das Gegenteil in Python zu lösen, da IE eine n, ich brauche die r, g, b Werte.

+0

Was meinst du mit RGB Integer? –

+1

http://www.shodor.org/stella2java/rgbint.html, einfach die Formel, die ich gerade in der Frage bearbeitet habe. '(255, 255, 255)' = '16777215' – Omar

Antwort

37

Ich bin kein Python-Experte mit allen Mitteln, aber soweit ich weiß, es hat die gleichen Operatoren wie C.

Wenn so sollte diese Arbeit, und es sollte auch viel schneller sein als Modulo verwenden und Aufteilung.

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

Was sie tut es die niedrigste Byte jeweils auszumaskieren (die binäre und mit 255 .. Ist gleich bis A 8 ein Bit). Für die grüne und rote Komponente tut es das gleiche, aber verschiebt den Farbkanal zuerst in das unterste Byte.

+1

+1 aber Geschwindigkeitsvorteil gegenüber einer Lösung, die% und // verwendet, sollte minimal sein. Sicherlich viel schneller als Lösungen mit Funktionsaufrufen (divmod, struct. [Un] pack, etc). –

14

Aus RGB integer:

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

Dies kann ziemlich einfach, wenn Sie implementiert werden, wie es zu bekommen. :)

Upd: Hinzugefügt Python-Funktion. Nicht sicher, ob es ein besserer Weg, es zu tun, aber das funktioniert auf Python 3 und 2,4

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

Es gibt auch eine ausgezeichnete Lösung, das bitshifting verwendet und Maskierung keinen Zweifel, viel schneller, dass Nils Pipenbrinck geschrieben.

+2

Vergessen Sie nicht, die Ganzzahldivision und nicht die Floatdivision zu verwenden. –

+0

Trotz der Tatsache, dass es ganzzahlige Division und Modulo verwendet, glaube ich nicht, dass meine Antwort eine Abwertung verdient. – Xorlev

+0

Nein, es verdient keinen Downvote. Die Leute haben den Tooltip von downvote-arrow nicht gelesen und glauben, dass "downvoting" bedeutet: "Ich mag das nicht." – tzot

0

Wahrscheinlich gibt es einen kürzeren Weg, dies zu tun:

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

EDIT: das ist falsch - gibt die Antwort in Hex, wollte OP int. EDIT2: verfeinert, um Elend und Fehler zu reduzieren - benötigt '% 06x', um sicherzustellen, dass hex immer als sechs Ziffern angezeigt wird [Danke an Peter Hansens Kommentar].

+1

Dies wird auch kläglich scheitern, wenn die Hex-Zeichenfolge nicht die erwarteten sechs Ziffern hat. Verwenden Sie "% 06x", um dies zu vermeiden. –

6

Ich nehme an, Sie haben eine 32-Bit-Ganzzahl mit den RGB-Werten (z. B. ARGB). Dann können Sie die binären Daten mit dem struct Modul auspacken:

# 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) 
+0

und wäre unglaublich langsam (2 Funktionsaufrufe) im Vergleich zu anderen Lösungen –

+0

Vielleicht nicht die praktischste, aber ist eine coole Lösung. – Rich

2
def unpack2rgb(intcol): 
    tmp, blue= divmod(intcol, 256) 
    tmp, green= divmod(tmp, 256) 
    alpha, red= divmod(tmp, 256) 
    return alpha, red, green, blue 

Wenn nur der divmod(value, (divider1, divider2, divider3…)) Vorschlag angenommen wurde, wäre es zu verschiedenen Zeitkonvertierungen vereinfacht.

9
>>> import struct 
>>> str='aabbcc' 
>>> struct.unpack('BBB',str.decode('hex')) 
(170, 187, 204) 

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

und

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

for python3: 
>>> bytes.hex(struct.pack('BBB',*rgb)) 
5
>>> r, g, b = (111, 121, 131) 
>>> packed = int('%02x%02x%02x' % (r, g, b), 16) 

Daraus ergibt sich die folgende integer:

>>> packed 
7305603 

Sie können es dann auspacken entweder die lange explizite Art und Weise:

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

..oder in einer kompakteren Weise:

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

Probe gilt mit einer beliebigen Anzahl von Ziffern, z RGBA Farbe:

>>> packed = int('%02x%02x%02x%02x' % (111, 121, 131, 141), 16) 
>>> [(packed >> (8*i)) & 255 for i in range(4)] 
[141, 131, 121, 111] 
3

Nur ein Hinweis für alle, mit Googles App Engine Bilder Python-API. Ich fand heraus, dass ich eine Situation hatte, in der ich eine Methode mit einem 32-Bit-RGB-Farbwert liefern musste. Wenn Sie die API zum Konvertieren eines PNG (oder eines Bildes mit transparenten Pixeln) verwenden, müssen Sie die Methode execute_transforms mit einem Argument namens transparent_substitution_rgb angeben, das eine 32-Bit-RGB-Farbe haben muss Wert.

Leihen von dbr Antwort, ich kam mit einem Verfahren ähnlich dem, dies:

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

Wenn Sie NumPy verwenden und haben eine Reihe von RGBints, können Sie auch nur seine dtype ändern, um die rot zu extrahieren , Grün-, Blau- und Alpha-Komponenten:

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

Hinzufügen zu dem, was oben erwähnt wird. Eine prägnante One-Liner-Alternative.

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

Und um jede Verwirrung in der Zukunft zu vermeiden.

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)