Skip to main content

How to convert colors in Python: A Comprehensive Guide to RGB, HSL, HWB, CMYK, and HEX

· 6 min read
Serhii Hrekov
software engineer, creator, artist, programmer, projects founder

Converting colors in Python is a fascinating mix of dictionary lookups (for names like "tomato") and coordinate geometry. While we can use the built-in colorsys module for some parts, we'll need the webcolors library to handle CSS names and some custom math to reach the more "exotic" formats like HWB and CMYK.


🎨 Understanding the Color Models

Before we code, it helps to visualize how these models differ. RGB is how your monitor thinks (light), CMYK is how your printer thinks (ink), and HSL/HWB are how humans think (perceptual).


💻 The Implementation

This tool uses a "Hub and Spoke" architecture: we convert any input into a standard RGB format first, then translate that RGB into all other formats.

1. Requirements

pip install webcolors

2. The Code

I have bundled the logic into a single, copy-pasteable script.

# 🌈 Python: The Ultimate All-in-One Color Converter

This tool handles CSS names, HEX, and standardizes everything into a unified report.

```python
import colorsys
import webcolors

def rgb_to_cmyk(r, g, b):
# Scale RGB to 0-1
r_prime, g_prime, b_prime = r/255, g/255, b/255
k = 1 - max(r_prime, g_prime, b_prime)
if k == 1:
return 0, 0, 0, 100
c = (1 - r_prime - k) / (1 - k)
m = (1 - g_prime - k) / (1 - k)
y = (1 - b_prime - k) / (1 - k)
return round(c*100), round(m*100), round(y*100), round(k*100)

def rgb_to_hwb(r, g, b):
# HWB: Hue, Whiteness, Blackness
r_p, g_p, b_p = r/255, g/255, b/255
h, s, l = colorsys.rgb_to_hls(r_p, g_p, b_p)
w = min(r_p, g_p, b_p)
b_val = 1 - max(r_p, g_p, b_p)
return round(h*360), round(w*100), round(b_val*100)

def convert_color(color_input):
try:
# 1. Normalize Input to RGB
if color_input.startswith('#'):
rgb = webcolors.hex_to_rgb(color_input)
else:
# Try to catch CSS names like 'tomato' or 'steelblue'
rgb = webcolors.name_to_rgb(color_input)

r, g, b = rgb.red, rgb.green, rgb.blue
r_p, g_p, b_p = r/255, g/255, b/255

# 2. Perform Conversions
hex_val = webcolors.rgb_to_hex((r, g, b))
h, l, s = colorsys.rgb_to_hls(r_p, g_p, b_p)
c, m, y, k = rgb_to_cmyk(r, g, b)
h_hwb, w_hwb, b_hwb = rgb_to_hwb(r, g, b)

# 3. Print Report
print(f"--- 🎨 Color Report for: {color_input} ---")
print(f"HEX : {hex_val.upper()}")
print(f"RGB : rgb({r}, {g}, {b})")
print(f"HSL : {round(h*360)}°, {round(s*100)}%, {round(l*100)}%")
print(f"HWB : {h_hwb}°, {w_hwb}%, {b_hwb}%")
print(f"CMYK : {c}%, {m}%, {y}%, {k}%")

except ValueError:
print(f"❌ Error: '{color_input}' is not a valid CSS name or HEX code.")

# --- Test it ---
convert_color("tomato")
print("\n")
convert_color("#4287f5")


📐 The Math Behind the Magic

While Python handles the heavy lifting, the formulas for these conversions are quite elegant.

CMYK Conversion

The "Key" (Black) is calculated first by finding the "distance" of the brightest color from white:


$$K = 1 - \max(R', G', B')$$

Then, Cyan, Magenta, and Yellow are calculated relative to that black value:

$$C = \frac{1 - R' - K}{1 - K}$$

HWB (Hue, Whiteness, Blackness)

HWB is often considered more intuitive for artists. You pick a Hue, then decide how much White to add to brighten it and how much Black to add to shade it.


📑 Comparison Table of Color Formats

FormatBest For...Component Logic
HEXWeb DevelopmentBase-16 shorthand for RGB.
RGBDigital ScreensAdditive light (Red, Green, Blue).
HSLUI/UX DesignHue (color), Saturation (vibrancy), Lightness.
CMYKPrint MediaSubtractive ink (Cyan, Magenta, Yellow, Key).
HWBHuman IntuitionSimple "mixing" of white and black paint.

📚 Sources & Technical Refs

More on python