Color math and conversion library for comprehensive color space transformations and color difference calculations.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Color objects represent colors in specific color spaces and provide the foundation for all color operations in colormath. The library supports 14+ color spaces with appropriate illuminant and observer configurations.
Foundation classes that provide common functionality for all color objects.
class ColorBase:
"""Base class for all color objects."""
def get_value_tuple(self):
"""Get color values as tuple."""
def set_observer(self, observer):
"""Set observer angle ('2' or '10')."""
def set_illuminant(self, illuminant):
"""Set illuminant (e.g., 'd65', 'a', 'c')."""
class IlluminantMixin:
"""Mixin for color spaces that support illuminants."""
def get_illuminant_xyz(self):
"""Get illuminant XYZ values."""
def apply_adaptation(self, target_illuminant, adaptation='bradford'):
"""Apply chromatic adaptation."""
class BaseRGBColor(ColorBase):
"""Base class for RGB color spaces."""
def get_upscaled_value_tuple(self):
"""Get RGB values scaled 0-255."""
def get_rgb_hex(self):
"""Convert RGB to hex string."""
@classmethod
def new_from_rgb_hex(cls, hex_str):
"""Create RGB color from hex string."""Standard CIE color spaces for device-independent color representation.
class XYZColor(ColorBase, IlluminantMixin):
"""CIE XYZ color space."""
def __init__(self, xyz_x, xyz_y, xyz_z, observer='2', illuminant='d50'):
"""
Create XYZ color.
Parameters:
- xyz_x, xyz_y, xyz_z: XYZ coordinates (0-1 range typically)
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name ('d65', 'a', 'c', etc.)
"""
class xyYColor(ColorBase, IlluminantMixin):
"""CIE xyY color space."""
def __init__(self, xyy_x, xyy_y, xyy_Y, observer='2', illuminant='d50'):
"""
Create xyY color.
Parameters:
- xyy_x, xyy_y: Chromaticity coordinates
- xyy_Y: Luminance value
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""
class LabColor(ColorBase, IlluminantMixin):
"""CIE L*a*b* color space."""
def __init__(self, lab_l, lab_a, lab_b, observer='2', illuminant='d50'):
"""
Create Lab color.
Parameters:
- lab_l: Lightness (0-100)
- lab_a: Green-red axis
- lab_b: Blue-yellow axis
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""
class LuvColor(ColorBase, IlluminantMixin):
"""CIE L*u*v* color space."""
def __init__(self, luv_l, luv_u, luv_v, observer='2', illuminant='d50'):
"""
Create Luv color.
Parameters:
- luv_l: Lightness (0-100)
- luv_u, luv_v: Chromaticity coordinates
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""
class LCHabColor(ColorBase, IlluminantMixin):
"""CIE LCH color space (via Lab)."""
def __init__(self, lch_l, lch_c, lch_h, observer='2', illuminant='d50'):
"""
Create LCH color via Lab.
Parameters:
- lch_l: Lightness (0-100)
- lch_c: Chroma
- lch_h: Hue angle (degrees)
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""
class LCHuvColor(ColorBase, IlluminantMixin):
"""CIE LCH color space (via Luv)."""
def __init__(self, lch_l, lch_c, lch_h, observer='2', illuminant='d50'):
"""
Create LCH color via Luv.
Parameters:
- lch_l: Lightness (0-100)
- lch_c: Chroma
- lch_h: Hue angle (degrees)
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""Device-dependent RGB color spaces for display and image processing.
class sRGBColor(BaseRGBColor):
"""Standard RGB color space."""
def __init__(self, rgb_r, rgb_g, rgb_b, is_upscaled=False):
"""
Create sRGB color.
Parameters:
- rgb_r, rgb_g, rgb_b: RGB values (0-1 or 0-255 if upscaled)
- is_upscaled: True if values are 0-255, False if 0-1
"""
class AdobeRGBColor(BaseRGBColor):
"""Adobe RGB color space."""
def __init__(self, rgb_r, rgb_g, rgb_b, is_upscaled=False):
"""
Create Adobe RGB color.
Parameters:
- rgb_r, rgb_g, rgb_b: RGB values (0-1 or 0-255 if upscaled)
- is_upscaled: True if values are 0-255, False if 0-1
"""Hue-based color spaces for intuitive color manipulation.
class HSLColor(ColorBase):
"""HSL color space."""
def __init__(self, hsl_h, hsl_s, hsl_l):
"""
Create HSL color.
Parameters:
- hsl_h: Hue (0-360 degrees)
- hsl_s: Saturation (0-1)
- hsl_l: Lightness (0-1)
"""
class HSVColor(ColorBase):
"""HSV color space."""
def __init__(self, hsv_h, hsv_s, hsv_v):
"""
Create HSV color.
Parameters:
- hsv_h: Hue (0-360 degrees)
- hsv_s: Saturation (0-1)
- hsv_v: Value (0-1)
"""Subtractive color spaces for printing applications.
class CMYColor(ColorBase):
"""CMY color space."""
def __init__(self, cmy_c, cmy_m, cmy_y):
"""
Create CMY color.
Parameters:
- cmy_c: Cyan (0-1)
- cmy_m: Magenta (0-1)
- cmy_y: Yellow (0-1)
"""
class CMYKColor(ColorBase):
"""CMYK color space."""
def __init__(self, cmyk_c, cmyk_m, cmyk_y, cmyk_k):
"""
Create CMYK color.
Parameters:
- cmyk_c: Cyan (0-1)
- cmyk_m: Magenta (0-1)
- cmyk_y: Yellow (0-1)
- cmyk_k: Black (0-1)
"""Full spectral power distribution representation for scientific applications.
class SpectralColor(ColorBase, IlluminantMixin):
"""Spectral power distribution color."""
def __init__(self,
spec_340nm=0.0, spec_350nm=0.0, spec_360nm=0.0, spec_370nm=0.0,
spec_380nm=0.0, spec_390nm=0.0, spec_400nm=0.0, spec_410nm=0.0,
spec_420nm=0.0, spec_430nm=0.0, spec_440nm=0.0, spec_450nm=0.0,
spec_460nm=0.0, spec_470nm=0.0, spec_480nm=0.0, spec_490nm=0.0,
spec_500nm=0.0, spec_510nm=0.0, spec_520nm=0.0, spec_530nm=0.0,
spec_540nm=0.0, spec_550nm=0.0, spec_560nm=0.0, spec_570nm=0.0,
spec_580nm=0.0, spec_590nm=0.0, spec_600nm=0.0, spec_610nm=0.0,
spec_620nm=0.0, spec_630nm=0.0, spec_640nm=0.0, spec_650nm=0.0,
spec_660nm=0.0, spec_670nm=0.0, spec_680nm=0.0, spec_690nm=0.0,
spec_700nm=0.0, spec_710nm=0.0, spec_720nm=0.0, spec_730nm=0.0,
spec_740nm=0.0, spec_750nm=0.0, spec_760nm=0.0, spec_770nm=0.0,
spec_780nm=0.0, spec_790nm=0.0, spec_800nm=0.0, spec_810nm=0.0,
spec_820nm=0.0, spec_830nm=0.0, observer='2', illuminant='d50'):
"""
Create spectral color with spectral power distribution data.
Parameters:
- spec_340nm through spec_830nm: Spectral reflectance values at each wavelength (0.0-1.0)
- observer: Observer angle ('2' or '10')
- illuminant: Illuminant name
"""
def calc_density(self):
"""Calculate density for this spectral color."""
def get_numpy_array(self):
"""Convert spectral data to NumPy array."""Specialized color spaces for specific applications.
class IPTColor(ColorBase):
"""IPT color space."""
def __init__(self, ipt_i, ipt_p, ipt_t):
"""
Create IPT color.
Parameters:
- ipt_i: Image (lightness)
- ipt_p: Protan (red-green)
- ipt_t: Tritan (yellow-blue)
"""from colormath.color_objects import LabColor, sRGBColor, XYZColor
# Create colors in different spaces
lab = LabColor(lab_l=50.0, lab_a=20.0, lab_b=-30.0)
rgb = sRGBColor(rgb_r=0.8, rgb_g=0.2, rgb_b=0.1)
xyz = XYZColor(xyz_x=0.4, xyz_y=0.3, xyz_z=0.2, illuminant='d50')from colormath.color_objects import sRGBColor
# Create RGB from 0-255 values
rgb = sRGBColor(255, 128, 64, is_upscaled=True)
# Convert to hex
hex_color = rgb.get_rgb_hex() # "#ff8040"
# Create RGB from hex
rgb_from_hex = sRGBColor.new_from_rgb_hex("#ff8040")from colormath.color_objects import SpectralColor
# Create spectral color with wavelength data
spectral = SpectralColor(
spec_340nm=0.050,
spec_400nm=0.064,
spec_410nm=0.065,
spec_420nm=0.066,
# ... continue for all wavelengths 340-830nm in 10nm intervals
spec_700nm=0.108,
spec_780nm=0.095,
spec_830nm=0.083,
observer='2',
illuminant='d65'
)
# Calculate density
density = spectral.calc_density()from colormath.color_objects import LabColor
# Create color with specific illuminant and observer
lab = LabColor(lab_l=50, lab_a=0, lab_b=0, observer='10', illuminant='a')
# Change illuminant
lab.set_illuminant('d50')
# Get illuminant XYZ values
illum_xyz = lab.get_illuminant_xyz()Install with Tessl CLI
npx tessl i tessl/pypi-colormath