2010-02-14 44 views
14

Làm cách nào để chuyển đổi một số nguyên RGB sang tuple RGB tương ứng (R,G,B)? Có vẻ đơn giản, nhưng tôi không thể tìm thấy bất cứ điều gì trên google.RGB Int to RGB - Python

Tôi biết rằng đối với mỗi RGB (r,g,b) bạn có số nguyên n = r256^2 + g256 + b, làm thế nào tôi có thể giải quyết điều ngược lại bằng Python, IE cho một n, tôi cần những r, g, b giá trị.

+0

Bạn có ý nghĩa gì với số nguyên RGB? –

+1

http://www.shodor.org/stella2java/rgbint.html, chỉ đơn giản là công thức tôi vừa chỉnh sửa trong câu hỏi. '(255, 255, 255)' = '16777215' – Omar

Trả lời

37

Tôi không phải là một chuyên gia về Python bằng mọi cách, nhưng như xa như tôi biết nó có người điều khiển tương tự như C.

Nếu vì thế này nên làm việc và nó cũng nên được nhanh hơn rất nhiều so với sử dụng modulo và chia.

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

Nó làm gì để che giấu byte thấp nhất trong mỗi trường hợp (nhị phân và 255 .. Tương đương với 8 bit). Đối với thành phần màu xanh lá cây và màu đỏ, nó cũng giống nhau, nhưng thay đổi kênh màu thành byte thấp nhất trước tiên.

+1

+1 lợi thế tốc độ so với giải pháp sử dụng% và // nên tối thiểu. Chắc chắn nhanh hơn nhiều so với các giải pháp với các cuộc gọi hàm (divmod, struct. [Un] pack, etc). –

14

Từ một số nguyên RGB:

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

này có thể được thực hiện khá đơn giản một khi bạn biết làm thế nào để có được nó. :)

Cập nhật: Đã thêm hàm python. Bạn không chắc chắn nếu có một cách tốt hơn để làm điều đó, nhưng hoạt động này trên Python 3 và 2,4

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

Ngoài ra còn có một giải pháp tuyệt vời mà sử dụng bitshifting và mặt nạ đó là không có nghi ngờ nhanh hơn nhiều mà Nils Pipenbrinck đăng.

+2

Đừng quên sử dụng phân chia số nguyên và không phân chia nổi. –

+0

Mặc dù thực tế là nó sử dụng phân chia số nguyên và modulo, tôi không nghĩ rằng câu trả lời của tôi xứng đáng với một downrate. – Xorlev

+0

Không, nó không xứng đáng với một downvote. Mọi người đã không đọc chú giải công cụ mũi tên xuống và tin rằng downvoting có nghĩa là "Tôi không thích điều này." – tzot

0

Có lẽ một cách ngắn hơn để làm điều này:

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

EDIT: điều này là sai - cung cấp cho câu trả lời trong Hex, OP muốn int. EDIT2: tinh chỉnh để giảm đau khổ và thất bại - cần thiết '% 06x' để đảm bảo hex luôn được hiển thị dưới dạng sáu chữ số [nhờ nhận xét của Peter Hansen].

+1

Điều này cũng sẽ thất bại thảm hại nếu chuỗi hex không có sáu chữ số được mong đợi. Sử dụng "% 06x" để tránh điều đó. Tuy nhiên, –

6

Tôi giả sử bạn có số nguyên 32 bit chứa giá trị RGB (ví dụ: ARGB). Sau đó, bạn có thể giải nén dữ liệu nhị phân bằng cách sử dụng mô-đun struct:

# 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

và sẽ rất chậm (2 cuộc gọi chức năng) so với các giải pháp khác –

+0

Có thể không phải là thực tế nhất nhưng là một giải pháp tuyệt vời. – 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 

Nếu chỉ đề nghị divmod(value, (divider1, divider2, divider3…)) đã được chấp nhận, nó sẽ đã đơn giản hóa chuyển đổi thời gian khác nhau quá.

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

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

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

này tạo ra các số nguyên sau:

>>> packed 
7305603 

Sau đó bạn có thể giải nén nó một trong hai cách rõ ràng dài:

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

..hoặc một cách nhỏ gọn hơn:

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

mẫu áp dụng với bất kỳ số lượng chữ số, ví dụ một màu RGBA:

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

Chỉ cần một lưu ý cho bất cứ ai sử dụng AppEngine Images Python API của Google. Tôi tìm thấy tôi đã có một tình huống mà tôi đã phải cung cấp một phương pháp với một giá trị màu RGB 32-bit. Cụ thể, nếu bạn đang sử dụng API để chuyển đổi PNG (hoặc bất kỳ hình ảnh nào có pixel trong suốt), bạn sẽ cần cung cấp phương thức execute_transforms với đối số được gọi là transparent_substitution_rgb phải là màu RGB 32 bit. giá trị.

Vay từ câu trả lời của DBR, tôi đã đưa ra một phương pháp tương tự như sau:

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

Nếu bạn đang sử dụng NumPy và bạn có một mảng của RGBints, bạn cũng có thể chỉ cần thay đổi dtype của nó để trích xuất các màu đỏ , các thành phần màu xanh lá cây, xanh dương và alpha:

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

Thêm vào những gì được đề cập ở trên. Một thay thế một lót ngắn gọn.

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

Và để tránh bất kỳ sự nhầm lẫn nào trong tương lai.

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)