API Documentation

Complete reference for every color algorithm used by OmniColor — conversion formulas, contrast calculation, harmony generation and more.

Overview

OmniColor does not have a hosted REST API — all tools run in your browser. This documentation describes the algorithms we use so you can implement them yourself in any programming language.

All algorithms use the sRGB color space (the standard for the web) unless otherwise noted. Formulas are per the W3C CSS Color Module Level 4 specification where applicable.

Color Conversions

HEX → RGB

Input: String, e.g. "#155EEF" or "155EEF"
Output: { r, g, b } — integers 0-255

Formula:

1. Strip the leading # if present
2. If 3 digits, expand each by doubling: "0AF" → "00AAFF"
3. Split into three 2-digit hex pairs (RR GG BB)
4. Convert each pair from hex to decimal (base 16 → base 10)
   R = parseInt(RR, 16), G = parseInt(GG, 16), B = parseInt(BB, 16)

Example: #155EEF → { r: 21, g: 94, b: 239 }

RGB → HEX

Input: { r, g, b } — integers 0-255
Output: Uppercase HEX string with # prefix

Formula:

1. Clamp each channel to [0, 255] and round to integer
2. Convert each to 2-digit hex: value.toString(16).padStart(2, '0')
3. Concatenate: '#' + hexR + hexG + hexB

Example: { r: 21, g: 94, b: 239 } → "#155EEF"

RGB → HSL

Input: { r, g, b } — integers 0-255
Output: { h: 0-360, s: 0-100, l: 0-100 }

Formula:

1. Normalize: r' = r/255, g' = g/255, b' = b/255
2. max = max(r', g', b'), min = min(r', g', b'), delta = max - min
3. L = (max + min) / 2
4. If delta = 0: H = 0, S = 0 (gray)
   Else:
     S = delta / (1 - |2L - 1|)
     If max = r': H = 60 × ((g' - b') / delta mod 6)
     If max = g': H = 60 × ((b' - r') / delta + 2)
     If max = b': H = 60 × ((r' - g') / delta + 4)
5. Convert H, S, L to integers: H × 1, S × 100, L × 100

HSL → RGB

Input: { h: 0-360, s: 0-100, l: 0-100 }
Output: { r, g, b } — integers 0-255

Formula:

1. Normalize: H = h/360, S = s/100, L = l/100
2. If S = 0: R = G = B = L (grayscale)
   Else:
     q = L < 0.5 ? L × (1 + S) : L + S - L × S
     p = 2L - q
     R = hue2rgb(p, q, H + 1/3)
     G = hue2rgb(p, q, H)
     B = hue2rgb(p, q, H - 1/3)

   hue2rgb(p, q, t):
     if t < 0: t += 1
     if t > 1: t -= 1
     if t < 1/6: return p + (q - p) × 6 × t
     if t < 1/2: return q
     if t < 2/3: return p + (q - p) × (2/3 - t) × 6
     return p

RGB → HSV

Input: { r, g, b }
Output: { h: 0-360, s: 0-100, v: 0-100 }

Formula:

1. Normalize: r' = r/255, g' = g/255, b' = b/255
2. max = max(r', g', b'), min = min(r', g', b'), delta = max - min
3. V = max
4. S = max === 0 ? 0 : delta / max
5. H computed the same way as in RGB → HSL

RGB → CMYK

Input: { r, g, b }
Output: { c, m, y, k } — percentages 0-100

Formula:

1. Normalize: r' = r/255, g' = g/255, b' = b/255
2. K = 1 - max(r', g', b')
3. If K = 1: C = M = Y = 0 (pure black)
   Else:
     C = (1 - r' - K) / (1 - K)
     M = (1 - g' - K) / (1 - K)
     Y = (1 - b' - K) / (1 - K)
4. Convert to percentages (× 100)

Note: RGB ↔ CMYK conversion is approximate. Screen and print color spaces have different gamuts. Exact conversion requires ICC profiles.

WCAG Contrast Ratio

Per WCAG 2.2 specification — required for accessibility validation.

Input: Two HEX colors
Output: Number from 1 to 21

Formula:

1. Convert both colors to RGB
2. Compute relative luminance of each:
   For each channel c ∈ {R, G, B}:
     c' = c / 255
     if c' ≤ 0.03928: c'' = c' / 12.92
     else: c'' = ((c' + 0.055) / 1.055) ^ 2.4
   L = 0.2126 × R'' + 0.7152 × G'' + 0.0722 × B''

3. Contrast ratio = (L_lighter + 0.05) / (L_darker + 0.05)

WCAG thresholds:
  AA Normal (4.5:1) — required for body text
  AA Large (3:1) — for 18pt+ text
  AAA Normal (7:1) — enhanced requirement
  AAA Large (4.5:1) — enhanced for large text

Color Harmonies

All harmonies operate on the hue value in HSL, keeping saturation and lightness constant from the base color.

Harmony Hue Offsets
Complementary[0°, 180°]
Analogous[-60°, -30°, 0°, +30°, +60°] (or ±30° for 3 colors)
Triadic[0°, 120°, 240°]
Tetradic (square)[0°, 90°, 180°, 270°]
Split-Complementary[0°, 150°, 210°]

Monochromatic

Same hue, varying lightness: [base_L - 30, base_L - 15, base_L, base_L + 15, base_L + 30], clamped to [10, 90]

Delta E (Color Difference)

Delta E CIE76 — the standard perceptual difference metric.

Formula:

1. Convert both colors to CIE Lab color space:
   RGB → XYZ → Lab (with D65 illuminant)

2. Delta E = sqrt((L1 - L2)² + (a1 - a2)² + (b1 - b2)²)

Interpretation:
  < 1.0    → imperceptible
  1.0 - 2.0 → only noticeable side-by-side
  2.0 - 10  → perceptible at a glance
  10 - 20   → clearly different
  20 - 50   → substantially different
  > 50     → very different colors

Color Temperature

Formula:

1. Convert to HSL
2. Classify based on hue:
   Warm: hue ≤ 60° OR hue ≥ 300°
   Cool: 160° ≤ hue < 300°
   Neutral: 60° < hue < 160°

Image Color Extraction

Algorithm used by OmniColor's image color picker:

1. Load image into memory (via FileReader or fetch)
2. Draw to canvas (downscale to ~100x100 for performance)
3. Extract pixel data via getImageData()
4. For each visible pixel (alpha > 10):
   - Quantize RGB to 32-step buckets: key = (r>>5, g>>5, b>>5)
   - Increment bucket count
5. Sort buckets by count descending
6. Take top N buckets as extracted palette
7. For each bucket, average the original RGB values

Error Handling

When implementing these algorithms:

  • Validate input: HEX must match /^#?[0-9a-f]{3,8}$/i
  • Clamp ranges: RGB to [0,255], H to [0,360), S/V/L to [0,100]
  • Handle edge cases: Black (#000000) has hue 0 by convention; gray colors have saturation 0
  • Round at output: Keep float precision during calculation

Reference Implementation

The complete, working implementation of every algorithm above is available in the OmniColor source:

/assets/js/color-utils.js      — All conversion functions
/assets/js/color-converters.js — Higher-level converters
/assets/js/tools/color-difference.js — Delta E calculation

These files are served unminified and viewable in any browser. You are free to learn from them. See our Copyright Policy for reuse terms.

Versioning

These algorithms follow the W3C CSS Color Module Level 4 specification. When the specification updates, we update our implementations. This documentation page reflects the current implementation as of November 2026.

Questions?

For developer inquiries about specific algorithms or implementation details, email developers@omnicolor.pages.dev.