konradmichalik/php-color

A small, framework-agnostic PHP library for color conversion, luminance, contrast and deterministic string-to-color hashing.

Maintainers

Package info

github.com/konradmichalik/php-color

pkg:composer/konradmichalik/php-color

Statistics

Installs: 200

Dependents: 3

Suggesters: 0

Stars: 0

Open Issues: 0

0.2.0 2026-06-19 11:30 UTC

This package is auto-updated.

Last update: 2026-06-19 12:01:07 UTC


README

Color

Coverage CGL Tests Supported PHP Versions License

A small, framework-agnostic PHP library for color conversion, luminance, contrast and deterministic string-to-color hashing. No runtime dependencies.

🚀 Features

  • Immutable Color value object with Rgb and Hsl companions
  • Lossless conversion between hex, RGB and HSL
  • Multi-format string parsing via fromString() / tryFromString()
  • CSS rgb() / rgba() output with optional alpha channel
  • WCAG 2.x relative luminance and contrast ratio
  • optimalTextColor() — pick readable text color for any background
  • Deterministic string → color hashing (SHA-256/HSL or CRC32)

🔥 Installation

Packagist Packagist Downloads

composer require konradmichalik/php-color

⚡ Usage

Conversion

use KonradMichalik\Color\Color;

$color = Color::fromHex('#3366cc');

$color->toRgb();          // Rgb(51, 102, 204)
$color->toHsl();          // Hsl(220.0, 60.0, 50.0)
$color->toHex();          // "#3366cc"

Color::fromRgb(51, 102, 204)->toHex();      // "#3366cc"
Color::fromHsl(220, 60, 50)->toHex();       // "#3366cc"
$color->withLightness(85)->toHex();         // a lighter variant (HSL space)
$color->scaleRgb(0.5)->toHex();             // halve each RGB channel → "#1a3366"
$color->darken(0.5)->toHex();               // alias for scaleRgb()

scaleRgb() multiplies every RGB channel by the factor (clamped to 0–255), while withLightness() works in HSL space — use scaleRgb() for plain per-channel brightness math. darken() is an alias. Factors below 0.0 throw InvalidColorValue:

use KonradMichalik\Color\ColorHasher;

ColorHasher::crc32()->hash($string)->scaleRgb(0.5)->toHex(); // darkened avatar color

Short hex (#abc), missing # and surrounding whitespace are all accepted. Invalid values throw KonradMichalik\Color\Exception\InvalidColorValue.

Parsing arbitrary strings

fromString() accepts hex, rgb(r, g, b) and hsl(h, s%, l%) in one call — whitespace is ignored, prefixes are case-insensitive and the HSL percent signs are optional:

Color::fromString('#ff0000');          // red
Color::fromString('f00');              // red
Color::fromString('rgb(255, 0, 0)');   // red
Color::fromString('hsl(0, 100%, 50%)'); // red
Color::fromString('HSL(0,100,50)');    // red

Use tryFromString() for fallbacks — it returns null instead of throwing:

Color::tryFromString($userInput) ?? Color::fromHex('#cccccc');

CSS output with alpha

$rgb = Color::fromHex('#ff0000')->toRgb();

$rgb->toCssString();        // "rgb(255, 0, 0)"
$rgb->toCssString(0.8);     // "rgba(255, 0, 0, 0.8)"

Color::fromHex('#ff0000')->toRgbaString(0.8); // "rgba(255, 0, 0, 0.8)"

The model stays RGB-only; alpha is an output concern. Values outside 0.0–1.0 throw KonradMichalik\Color\Exception\InvalidColorValue.

Contrast & readable text

$background = Color::fromHex('#222222');

$background->relativeLuminance();                  // 0.0185…
$background->contrastRatio(Color::fromHex('#fff')); // 15.9…
$background->isDark();                              // true
$background->optimalTextColor()->toHex();          // "#ffffff"

optimalTextColor() returns whichever candidate (black/white by default, or two custom colors) has the higher contrast against the background.

Deterministic colors from strings

Great for avatar backgrounds or tag colors — the same input always yields the same color:

use KonradMichalik\Color\ColorHasher;

$hasher = ColorHasher::hsl();              // balanced SHA-256 → HSL (recommended)
$hasher->hash('konrad@example.com');       // stable Color

$hasher = ColorHasher::hsl(saturation: 70, lightness: 45);
$hasher = ColorHasher::crc32();            // lightweight CRC32 → hex

Need a custom mapping? Implement KonradMichalik\Color\Hashing\HashStrategy and pass it to new ColorHasher($strategy).

🧑‍💻 Contributing

Please have a look at CONTRIBUTING.md.

📄 License

This project is licensed under GPL-2.0-or-later.