Skip to main content

How to Convert RGB to Hex Codes in Python

In digital design and web development, colors are often manipulated as RGB tuples, (Red, Green, Blue) integers ranging from 0 to 255, but required by CSS and HTML as Hexadecimal strings (e.g., #FF5733).

This guide explains how to efficiently convert RGB values to Hex codes using Python's string formatting capabilities, specifically focusing on f-strings and handling common formatting pitfalls like zero-padding.

Understanding the Data Formats

  • RGB: Represented as a tuple of three integers, e.g., (255, 0, 128).
  • Hex: A string starting with # followed by 6 characters (0-9, A-F). Each pair of characters represents a color channel in base-16.

Introduced in Python 3.6, f-strings provide the most readable and concise way to perform this conversion.

The format specifier :02x is the key:

  • 0: Pad with zeros if the number is small.
  • 2: Ensure the output is at least 2 characters wide.
  • x: Convert to lowercase hexadecimal (use X for uppercase).
rgb = (255, 165, 0) # Orange

# ✅ Solution: Unpack the tuple into r, g, b variables
r, g, b = rgb

# Use f-string formatting
hex_code_lower = f"#{r:02x}{g:02x}{b:02x}"
hex_code_upper = f"#{r:02X}{g:02X}{b:02X}"

print(f"Lower: {hex_code_lower}")
print(f"Upper: {hex_code_upper}")

Output:

Lower: #ffa500
Upper: #FFA500
tip

Using *rgb inside the format string is not supported directly in this manner. It is cleaner to unpack r, g, b first or access indices rgb[0], rgb[1], etc.

Method 2: Using the format() Method

For older Python versions (pre-3.6), the .format() string method is the standard approach. It uses the same format specifiers as f-strings.

rgb = (0, 128, 255) # A shade of blue

# ✅ Solution: Using .format()
# We can use the splat operator (*) to unpack the tuple directly
hex_code = "#{:02X}{:02X}{:02X}".format(*rgb)

print(f"Hex: {hex_code}")

Output:

Hex: #0080FF

Common Pitfall: Missing Zero Padding

A standard hex code must be 6 characters long (plus the hash). A common mistake is using the standard hex() function or simple formatting without padding. If a color value is less than 16 (e.g., 10), it converts to a single digit (a), resulting in an invalid hex code like #fa5 (ambiguous length).

r, g, b = (255, 10, 5)

# ⛔️ Incorrect: No padding specified
# hex(10) returns '0xa', hex(5) returns '0x5'
bad_hex = f"#{r:x}{g:x}{b:x}"
print(f"Invalid Hex: {bad_hex}")

# ✅ Correct: Force 2 digits with '02'
good_hex = f"#{r:02x}{g:02x}{b:02x}"
print(f"Valid Hex: {good_hex}")

Output:

Invalid Hex: #ffa5
Valid Hex: #ff0a05

Common Pitfall: Values Out of Range

RGB values must be between 0 and 255. If user input provides values outside this range (e.g., 300 or -50), the conversion will result in nonsense hex codes unless you clamp the values.

def to_hex_safe(r, g, b):
# ⛔️ Risky: r=300 becomes #12C (3 chars) breaking the format
# unsafe = f"#{r:02x}{g:02x}{b:02x}"

# ✅ Correct: Clamp values to 0-255 range
r = max(0, min(r, 255))
g = max(0, min(g, 255))
b = max(0, min(b, 255))

return f"#{r:02X}{g:02X}{b:02X}"

print(to_hex_safe(300, 100, -20))

Output:

#FF6400
note

In the example above, 300 was clamped to 255 (FF), and -20 was clamped to 0 (00).

Conclusion

To convert RGB integers to Hex strings in Python:

  1. Use f-strings (f"#{r:02x}{g:02x}{b:02x}") for modern, readable code.
  2. Use X for uppercase and x for lowercase hex digits.
  3. Always include :02 to pad single-digit hex numbers with a leading zero.
  4. Clamp inputs if there is a risk of data falling outside the 0-255 range.