การแปลงทูเพิลสี RGB เป็นรหัสหกหลักใน Python


93

ฉันต้องการแปลง (0, 128, 64) เป็นอะไรแบบนี้ # 008040 ฉันไม่แน่ใจว่าจะเรียกว่าอะไรทำให้ค้นหายาก


ดูคำตอบ SO ก่อนหน้าstackoverflow.com/questions/214359/… -จากสามคำตอบหนึ่งที่ได้รับการโหวตมากที่สุดรวมถึงข้อมูลโค้ด python แบบสแตนด์อโลนเพื่อทำในสิ่งที่ฉันเชื่อว่าคุณเป็น
doug

3
คำที่คุณกำลังมองหาคือ Hex Triplet en.wikipedia.org/wiki/Hex_color#Hex_triplet
Mark Ransom

สำหรับคำถามทั่วไปพร้อมคำตอบที่ดีกว่าที่นี่: stackoverflow.com/a/57197866/624066
MestreLion

คำตอบ:


191

ใช้ตัวดำเนินการรูปแบบ%:

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

โปรดทราบว่าจะไม่ตรวจสอบขอบเขต ...

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

ขีด จำกัด 2 หลักจำเป็นจริงหรือ? ตราบเท่าที่ค่า RGB อยู่ในขอบเขตที่เหมาะสมคือ 0-255 คุณไม่ควรจำเป็นต้องใช้ ดังนั้นคุณก็สามารถทำ'#%x%x%x' % (r, g, b)
wordsforthewise

3
ที่จริงแล้วตอนนี้ฉันเห็นว่าถ้าคุณมีค่า 0 มันจะต้องใส่ 0 อีกตัวดังนั้น 02 จึงจะทำให้มันเป็นสองหลัก
พูด

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

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

นี้จะใช้วิธีการที่ต้องการของสตริงการจัดรูปแบบตามที่อธิบายไว้ใน PEP 3101 นอกจากนี้ยังใช้min()และเพื่อให้มั่นใจว่าmax0 <= {r,g,b} <= 255

อัปเดตได้เพิ่มฟังก์ชันแคลมป์ตามคำแนะนำด้านล่าง

อัปเดตจากชื่อคำถามและบริบทที่ระบุควรชัดเจนว่าสิ่งนี้คาดหวัง 3 ints ใน [0,255] และจะส่งคืนสีเสมอเมื่อผ่าน 3 ints ดังกล่าว อย่างไรก็ตามจากความคิดเห็นนี้อาจไม่ชัดเจนสำหรับทุกคนดังนั้นขอให้ระบุอย่างชัดเจน:

ให้intค่าสามค่านี้จะส่งคืนค่า hex triplet ที่ถูกต้องซึ่งแสดงถึงสี หากค่าเหล่านั้นอยู่ระหว่าง [0,255] ค่าเหล่านั้นจะถือว่าเป็นค่า RGB และส่งคืนสีที่สอดคล้องกับค่าเหล่านั้น


20

นี่เป็นคำถามเก่า แต่สำหรับข้อมูลฉันได้พัฒนาแพ็คเกจที่มียูทิลิตี้บางอย่างที่เกี่ยวข้องกับสีและ colormaps และมีฟังก์ชัน rgb2hex ที่คุณต้องการแปลง triplet เป็นค่า hexa (ซึ่งสามารถพบได้ในแพ็คเกจอื่น ๆ เช่น matplotlib) มันอยู่บน pypi

pip install colormap

แล้ว

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

ตรวจสอบความถูกต้องของอินพุต (ค่าต้องอยู่ระหว่าง 0 ถึง 255)


3
ฉันพยายามใช้ rgb2hex แต่พบข้อผิดพลาด "ImportError: No module named easydev.tools" คุณสามารถแนะนำวิธีแก้ปัญหาได้หรือไม่?
Abhils

ลองติดตั้ง easydev ใหม่ จากนั้น 'pip3 ติดตั้ง easydev'
Shounak Ray

16

ฉันได้สร้างโปรแกรม python แบบเต็มแล้วฟังก์ชันต่อไปนี้สามารถแปลง rgb เป็น hex และในทางกลับกัน

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

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

คุณสามารถดูโค้ดและบทช่วยสอนทั้งหมดได้ที่ลิงค์ต่อไปนี้: การแปลงRGB เป็น Hex และ Hex เป็น RGB โดยใช้ Python


ไม่ทำงานสำหรับค่าทศนิยมของ rgb คุณช่วยแนะนำวิธีแก้ปัญหาให้ฉันได้ไหม
Abhils

รอบ. ไม่ควรมีความแตกต่างกันมากในสีสุดท้าย
Shounak Ray

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

หรือ

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

python3 แตกต่างกันเล็กน้อย

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

3

นี่คือฟังก์ชั่นที่สมบูรณ์มากขึ้นในการจัดการกับสถานการณ์ที่คุณอาจจะมีค่า RGB ในช่วง[0,1]หรือช่วง[0255]

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!
Sunghee Yun

3

โปรดทราบว่าสิ่งนี้ใช้ได้กับ python3.6 ขึ้นไปเท่านั้น

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

ข้างต้นเทียบเท่ากับ:

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

ฟังก์ชั่นนี้ rgb2hex ใช้กับ (13,13,12) ให้ 0xDDC แต่เว็บไซต์ RGB เป็น HEX ให้เป็น 0x0D0D0C และสิ่งนี้ก็สอดคล้องกับแนวคิดที่ว่าตัวเลขควรเป็น 13 * 65536 + 13 * 256 + 12 และ 0xDDC อ่านโดย Python เป็น 3548
Lars Ericson

CSS สีไม่สอดคล้องกัน มีสีเลขฐานสิบหก 6 หลักสีฐานสิบหก 3 หลักสัญกรณ์ rgb พร้อมทศนิยมและเปอร์เซ็นต์ hsl ฯลฯ ฉันได้ปรับแต่งสูตรเพื่อให้มีสีฐานสิบหก 6 หลักเสมอและแม้ว่าฉันคิดว่ามันอาจจะสอดคล้องกันมากขึ้น แต่ฉัน ไม่แน่ใจว่าถูกต้องกว่านี้
Brian Bruggeman

3

คุณสามารถใช้ lambda และ f-strings (มีใน 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))

การใช้งาน

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


1
ไม่แนะนำให้โทรหา lambda โดยตรงด้วยเหตุผลหลายประการ ฉันใช้มันแบบนี้กับโปรเจ็กต์ที่ได้รับการตรวจสอบและทุกคนก็พูดเหมือนกันไม่ใช่โทรมาโดยตรง
MikeyB

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

background = RGB(0, 128, 64)

ฉันรู้ว่า one-liners ใน Python ไม่จำเป็นต้องดูด้วยความกรุณา แต่มีหลายครั้งที่ฉันอดไม่ได้ที่จะใช้ประโยชน์จากสิ่งที่ตัวแยกวิเคราะห์ Python อนุญาต เป็นคำตอบเดียวกับโซลูชันของ Dietrich Epp (ดีที่สุด) แต่รวมอยู่ในฟังก์ชันบรรทัดเดียว ดังนั้นขอขอบคุณ Dietrich!

ตอนนี้ฉันใช้มันกับ tkinter :-)


1

ในPython 3.6คุณสามารถใช้f-stringsเพื่อทำความสะอาดได้:

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

แน่นอนคุณสามารถใส่มันลงในฟังก์ชันได้และในฐานะโบนัสค่าจะถูกปัดเศษและแปลงเป็น int :

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

rgb2hex(*rgb)

1

คุณยังสามารถใช้ตัวดำเนินการที่ชาญฉลาดซึ่งค่อนข้างมีประสิทธิภาพแม้ว่าฉันสงสัยว่าคุณจะกังวลเกี่ยวกับประสิทธิภาพของสิ่งนี้ นอกจากนี้ยังค่อนข้างสะอาด หมายเหตุไม่ได้ยึดหรือตรวจสอบขอบเขต นี้ได้รับการสนับสนุนอย่างน้อยตั้งแต่หลาม 2.7.17

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

และหากต้องการเปลี่ยนแปลงให้เริ่มต้นด้วย # คุณสามารถทำได้:

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

1

ฉันแปลกใจจริงๆที่ไม่มีใครแนะนำแนวทางนี้:

สำหรับ Python 2 และ 3:

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

Python 3.6+:

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

เป็นฟังก์ชัน:

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.