Skip to main content

LCh Color Space

LCh (Lightness, Chroma, Hue) is a polar representation of Lab color space. It's particularly useful for perceptual color manipulation and creating color harmonies, as it separates lightness, color intensity, and color direction.

Channels

LCh has three channels:

  • l (Lightness): Perceptual lightness, 0-100
  • c (Chroma): Color intensity or saturation, 0-100+
  • h (Hue): Color direction, 0-360 degrees

Channel Ranges

  • Lightness (l): 0-100
    • 0 = Black
    • 50 = Middle gray
    • 100 = White
  • Chroma (c): 0-100+ (theoretical maximum depends on lightness and hue)
    • 0 = No color (gray)
    • Higher values = More intense color
  • Hue (h): 0-360 degrees
    • = Red
    • 90° = Yellow
    • 180° = Green
    • 270° = Blue
    • 360° = Red (wraps around)

Default Values

All channels default to 0 when not specified, resulting in black (lch(0, 0, 0)).

CIE Standard Support

LCh supports CIE Standard Illuminants and Observers, just like Lab:

  • Illuminants: A, B, C, D50, D55, D65, D75, E, F1-F12
  • Observers: 2° (1931) and 10° (1964)

The default is D65 illuminant with 2° observer.

Creating LCh Colors

use Negarity\Color\Color;

// Create an LCh color with default illuminant/observer
$color = Color::lch(50, 30, 210);

// Create with specific illuminant and observer
$color = Color::lch(50, 30, 210,
CIEIlluminant::D50,
CIEObserver::TenDegree
);

Working with LCh Channels

Getting Channel Values

$color = Color::lch(75, 45, 240);

$l = $color->getL(); // 75
$c = $color->getC(); // 45
$h = $color->getH(); // 240

Checking Channel Existence

use Negarity\Color\ColorSpace\LCh;

LCh::hasChannel('l'); // true
LCh::hasChannel('c'); // true
LCh::hasChannel('h'); // true
LCh::hasChannel('a'); // false (that's Lab)

Getting Channel Defaults

use Negarity\Color\ColorSpace\LCh;

LCh::getChannelDefaultValue('l'); // 0
LCh::getChannelDefaultValue('c'); // 0
LCh::getChannelDefaultValue('h'); // 0

Getting All Channels

use Negarity\Color\ColorSpace\LCh;

LCh::getChannels(); // ['l', 'c', 'h']

Checking CIE Support

use Negarity\Color\ColorSpace\LCh;

LCh::supportsIlluminant(); // true
LCh::supportsObserver(); // true

Validation

LCh validates channel values:

use Negarity\Color\Color;
use Negarity\Color\Exception\InvalidColorValueException;

try {
// This will throw InvalidColorValueException
$color = Color::lch(150, 30, 210); // Lightness exceeds 100
} catch (InvalidColorValueException $e) {
// Handle error
}

try {
// This will also throw InvalidColorValueException
$color = Color::lch(50, 30, 400); // Hue exceeds 360
} catch (InvalidColorValueException $e) {
// Handle error
}

Understanding LCh

Relationship to Lab

LCh is a polar (cylindrical) representation of Lab:

  • L (Lightness): Same as Lab's L channel
  • C (Chroma): Distance from the neutral axis (calculated from a and b)
  • H (Hue): Angle around the neutral axis (calculated from a and b)

The conversion is:

  • C = sqrt(a² + b²)
  • H = atan2(b, a)

Advantages of LCh

  1. Intuitive Manipulation: Easy to adjust lightness, saturation (chroma), and hue independently
  2. Color Harmonies: Simple to create complementary, triadic, or analogous colors
  3. Perceptual Uniformity: Inherits Lab's perceptual uniformity
  4. Separation of Concerns: Lightness, color intensity, and color direction are clearly separated

Chroma vs Saturation

  • Chroma: Absolute color intensity (distance from gray)
  • Saturation: Relative color intensity (chroma relative to lightness)

In LCh, chroma is absolute, making it easier to work with than HSL's saturation.

Use Cases

  • Color Harmonies: Creating complementary, triadic, or analogous color schemes
  • Perceptual Color Manipulation: Adjusting colors in a perceptually uniform way
  • Color Design: Intuitive color adjustments for design work
  • Color Analysis: Analyzing color relationships and differences
  • Accessibility: Adjusting colors while maintaining perceptual relationships

Color Space Information

use Negarity\Color\ColorSpace\LCh;

LCh::getName(); // "lch"
LCh::getChannels(); // ['l', 'c', 'h']
LCh::supportsIlluminant(); // true
LCh::supportsObserver(); // true

See Also