PHP Classes

File: StarColor.class.php

Recommend this page to a friend!
  Classes of Shaun Moss   StarColor   StarColor.class.php   Download  
File: StarColor.class.php
Role: Class source
Content type: text/plain
Description: The StarColor class file.
Class: StarColor
Process and convert color values between formats
Author: By
Last change:
Date: 12 years ago
Size: 36,983 bytes
 

Contents

Class file image Download
<?php /** * StarColor class. * * @author Shaun Moss * @version 2012-08-11 * * @todo TEST THIS CLASS! * * @idea Also provide properties for cyan, magenta, yellow and black. */ class StarColor { /** * The color value, a 32-bit integer with bytes organised as ARGB. * * @var int */ protected $value; /** * Constructor. Multiple function signatures supported. * * General pattern: * new StarColor(); * new StarColor($color); * new StarColor($color, $alpha); * new StarColor($red, $green, $blue); * new StarColor($red, $green, $blue, $alpha); * new StarColor($hue, $saturation, $lightness, TRUE); * new StarColor($hue, $saturation, $lightness, $alpha, TRUE); * * $color can be: * - a hex color string (3 or 6-digit, with or without leading '#') * - a color name or 'transparent' * - a 24-bit RGB integer, as would be returned from imagecolorat() * - a StarColor object to clone * - CSS-style color string of the form: * - 'rgb(red, green, blue)' * - 'rgba(red, green, blue, alpha)' * - 'hsl(hue, saturation, lightness)' * - 'hsla(hue, saturation, lightness, alpha)' * * $red, $green and $blue can be: * - integer from 0..255 * - string from 0%..100% * * $alpha, $saturation and $lightness can be: * - float from 0.0..1.0 * - string from 0%..100% * * $hue can be any float, which will be normalized to the range [0..360) * * NOTE if alpha is defined in both the first and second params, they will be multiplied. * * Examples: * * Hex #rrggbb: * new StarColor('#ABCDEF'); * new StarColor('#ABCDEF', 0.75); * new StarColor('#ABCDEF', '75%'); * new StarColor('ABCDEF'); * new StarColor('ABCDEF', 0.75); * new StarColor('ABCDEF', '75%'); * * Hex #rgb: * new StarColor('#ABC'); * new StarColor('#ABC', 0.75); * new StarColor('#ABC', '75%'); * new StarColor('ABC'); * new StarColor('ABC', 0.75); * new StarColor('ABC', '75%'); * * Named colors: * new StarColor('Orange'); * new StarColor('Orange', 0.75); * new StarColor('Orange', '75%'); * new StarColor('Transparent'); * * 24-bit color integer: * new StarColor(0xABCDEF); * new StarColor(0xABCDEF, 0.75); * new StarColor(0xABCDEF, '75%'); * new StarColor(imagecolorat($image, $x, $y)); * new StarColor(imagecolorat($image, $x, $y), 0.75); * new StarColor(imagecolorat($image, $x, $y), '75%'); * * Clone: * new StarColor($otherStarColorObject); * new StarColor($otherStarColorObject, 0.75); * new StarColor($otherStarColorObject, '75%'); * * RGBA: * new StarColor(100, 200, 150); * new StarColor(100, 200, 150, 0.75); * new StarColor(100, 200, 150, '75%'); * new StarColor('30%', '50%', '40%'); * new StarColor('30%', '50%', '40%', 0.75); * new StarColor('30%', '50%', '40%', '75%'); * * HSLA: * new StarColor(120, '80%', '30%', TRUE); * new StarColor(120, '80%', '30%', 0.75, TRUE); * new StarColor(120, '80%', '30%', '75%', TRUE); * * CSS : * new StarColor('rgb(100, 200, 150)'); * new StarColor('rgba(100, 200, 150, 0.75)'); * new StarColor('rgb(30%, 90%, 12%)'); * new StarColor('rgba(30%, 90%, 12%, 0.75)'); * new StarColor('hsl(120, 59%, 72%)'); * new StarColor('hsla(120, 59%, 72%, 0.75)'); * * Array: * new StarColor(array('red' => 100, 'green' => 200, 'blue' => 150)); * new StarColor(array('red' => 100, 'green' => 200, 'blue' => 150), 0.75); * new StarColor(array('red' => 100, 'green' => 200, 'blue' => 150), '75%'); * new StarColor(array('red' => 100, 'green' => 200, 'blue' => 150, 'alpha' => 0.75)); * * @param string|int|float|StarColor $param1 * Color string or int, StarColor, red, or hue * @param string|int|float $param2 * Alpha, green or saturation * @param string|int|float $param3 * Blue or lightness * @param string|float|bool $param4 * Alpha value or FALSE for RGB, TRUE for HSL * @param bool $param5 * TRUE for HSL, FALSE for RGB (default) */ public function __construct($param1 = NULL, $param2 = NULL, $param3 = NULL, $param4 = NULL, $param5 = FALSE) { $n_args = func_num_args(); if ($n_args == 0) { // Default to black: $this->rgba(0, 0, 0, 1); return; } if ($n_args <= 2) { // Second param is alpha, default to 1: $alpha = self::normalizeFraction($param2); if (is_numeric($param1)) { // Integer representing a 24-bit RGB color, as would be supplied by imagecolorat(). $this->value = (((int) $param1) & 0xFFFFFF) << 8; $this->alpha($alpha); return; } if (is_string($param1)) { // Transparent: if (strcasecmp($param1, 'transparent') == 0) { // Use same value as CSS for transparent. Alpha is 0, color is black by default. $this->value = 0; return; } // Check for color name: if (self::isColorName($param1)) { $rgb = self::hex2rgb(self::colorName2hex($param1)); $this->rgba($rgb['red'], $rgb['green'], $rgb['blue'], $alpha); return; } // Check for hex color string: if (self::isHexString($param1)) { $rgb = self::hex2rgb($param1); $this->rgba($rgb['red'], $rgb['green'], $rgb['blue'], $alpha); return; } // Regular expressions: $num = "((\d*\.)?\d+)"; $pc = "\s*($num%?)\s*"; $deg = "\s*(-?$num)\s*"; // Check for rgb(): $pattern = "/^rgb\($pc,$pc,$pc\)$/i"; $n_matches = preg_match($pattern, $param1, $matches); if ($n_matches) { $this->rgba($matches[1], $matches[4], $matches[7], $alpha); return; } // Check for rgba(): $pattern = "/^rgba\($pc,$pc,$pc,$pc\)$/i"; $n_matches = preg_match($pattern, $param1, $matches); if ($n_matches) { $alpha *= self::normalizeFraction($matches[10]); $this->rgba($matches[1], $matches[4], $matches[7], $alpha); return; } // Check for hsl(): $pattern = "/^hsl\($deg,$pc,$pc\)$/i"; $n_matches = preg_match($pattern, $param1, $matches); if ($n_matches) { $this->hsla($matches[1], $matches[4], $matches[7], $alpha); return; } // Check for hsla(): $pattern = "/^hsla\($deg,$pc,$pc,$pc\)$/i"; $n_matches = preg_match($pattern, $param1, $matches); if ($n_matches) { $alpha *= self::normalizeFraction($matches[10]); $this->hsla($matches[1], $matches[4], $matches[7], $alpha); return; } } if (is_array($param1)) { // RGB or RGBA array. $red = isset($param1['red']) ? $param1['red'] : 0; $green = isset($param1['green']) ? $param1['green'] : 0; $blue = isset($param1['blue']) ? $param1['blue'] : 0; $alpha2 = isset($param1['alpha']) ? $param1['alpha'] : 1; $this->rgba($red, $green, $blue, $alpha * $alpha2); return; } if ($param1 instanceof StarColor) { // Copy the object, taking into account the alpha parameter if provided: $rgba = $param1->rgba(); $this->rgba($rgba['red'], $rgba['green'], $rgba['blue'], $rgba['alpha'] * $alpha); return; } } elseif ($n_args >= 3) { if ($n_args == 3) { // RGB with no alpha: $alpha = 1; $hsl = FALSE; } elseif ($n_args == 4) { if (is_bool($param4)) { // HSL or RGB with unspecified alpha, default to 1: $alpha = 1; $hsl = $param4; } else { // RGB with alpha: $alpha = (float) $param4; $hsl = FALSE; } } else { // HSL or RGB with alpha: $alpha = (float) $param4; $hsl = (bool) $param5; } if ($hsl) { $this->hsla($param1, $param2, $param3, $alpha); } else { $this->rgba($param1, $param2, $param3, $alpha); } return; } trigger_error("Invalid parameters for StarColor constructor.", E_USER_WARNING); } /////////////////////////////////////////////////////////////////////////// // Methods for getting/setting properties. /** * Gets/sets the 32-bit RGBA color value. * * @param null|int $value * 0..0xFFFFFFFF * @return int|null * 0..0xFFFFFFFF */ public function value($value = NULL) { if ($value === NULL) { // Get the value: return $this->value; } // Set the value. Convert to 32-bit int: $this->value = ((int) $value) & 0xFFFFFFFF; return $this; } /** * Gets/sets the red value. * * @param null|int|string $red * 0..255 or 0%..100% * @return int|null * 0..255 */ public function red($red = NULL) { if ($red === NULL) { // Get the red value: return ($this->value >> 24) & 0xFF; } // Set the red value: $red = self::normalizeByte($red); $this->value = ($this->value & 0x00FFFFFF) | ($red << 24); return $this; } /** * Gets/sets the green value. * * @param null|int|string $green * 0..255 or 0%..100% * @return int|null * 0..255 */ public function green($green = NULL) { if ($green === NULL) { // Get the green value: return ($this->value >> 16) & 0xFF; } // Set the green value: $green = self::normalizeByte($green); $this->value = ($this->value & 0xFF00FFFF) | ($green << 16); return $this; } /** * Gets/sets the blue value. * * @param null|int|string $blue * 0..255 or 0%..100% * @return int|null * 0..255 */ public function blue($blue = NULL) { if ($blue === NULL) { // Get the blue value: return ($this->value >> 8) & 0xFF; } // Set the blue value: $blue = self::normalizeByte($blue); $this->value = ($this->value & 0xFFFF00FF) | ($blue << 8); return $this; } /** * Gets/sets the alpha value. * * @param null|float|string $alpha * 0.0..1.0 or 0%..100% * @return float|null * 0.0..1.0 */ public function alpha($alpha = NULL) { if ($alpha === NULL) { // Get the alpha value as a fraction in the range 0.0..1.0: return ($this->value & 0xFF) / 255; } // Set the alpha value: $alpha = self::normalizeFractionByte($alpha); $this->value = ($this->value & 0xFFFFFF00) | $alpha; return $this; } /** * Gets/sets the hue. * * @param null|float $hue * 0..360 * @return float|null * 0..360 */ public function hue($hue = NULL) { if ($hue === NULL) { // Get the hue: $hsl = $this->hsl(); return $hsl['hue']; } // Set the hue: $hue = self::normalizeDegree($hue); $hsl = $this->hsl(); $this->hsl($hue, $hsl['saturation'], $hsl['lightness']); return $this; } /** * Gets/sets the saturation. * * @param null|float|string $saturation * 0.0..1.0 or 0%..100% * @return float|null * 0.0..1.0 */ public function saturation($saturation = NULL) { if ($saturation === NULL) { // Get the saturation: $hsl = $this->hsl(); return $hsl['saturation']; } // Set the saturation: $saturation = self::normalizeFraction($saturation); $hsl = $this->hsl(); $this->hsl($hsl['hue'], $saturation, $hsl['lightness']); return $this; } /** * Gets/sets the lightness. * * @param null|float|string $lightness * 0.0..1.0 or 0%..100% * @return float|null * 0.0..1.0 */ public function lightness($lightness = NULL) { if ($lightness === NULL) { // Get the lightness: $hsl = $this->hsl(); return $hsl['lightness']; } // Set the lightness: $lightness = self::normalizeFraction($lightness); $hsl = $this->hsla(); $this->hsl($hsl['hue'], $hsl['saturation'], $lightness); return $this; } /////////////////////////////////////////////////////////////////////////// // Public methods for getting/setting multiple properties. /** * Gets/sets all RGBA values. * * @param null|int|string $red * 0..255 or 0%..100% * @param null|int|string $green * 0..255 or 0%..100% * @param null|int|string $blue * 0..255 or 0%..100% * @param null|float|string $alpha * 0.0..1.0 or 0%..100% * @return array */ public function rgba($red = NULL, $green = NULL, $blue = NULL, $alpha = NULL) { if ($red === NULL) { // Get the RGBA values: return array_merge($this->rgb(), array('alpha' => $this->alpha())); } // Set the RGBA values: $this->red($red); $this->green($green); $this->blue($blue); $this->alpha($alpha); return $this; } /** * Gets/sets all RGB values. * * @param null|int|string $red * 0..255 or 0%..100% * @param null|int|string $green * 0..255 or 0%..100% * @param null|int|string $blue * 0..255 or 0%..100% * @return array */ public function rgb($red = NULL, $green = NULL, $blue = NULL) { if ($red === NULL) { // Get the RGB values: return array( 'red' => $this->red(), 'green' => $this->green(), 'blue' => $this->blue(), ); } // Set the RGB values: $this->red($red); $this->green($green); $this->blue($blue); return $this; } /** * Gets/sets all HSLA values. * * @param null|float $hue * 0..360 * @param null|float|string $saturation * 0.0..1.0 or 0%..100% * @param null|float|string $lightness * 0.0..1.0 or 0%..100% * @param null|float|string $alpha * 0.0..1.0 or 0%..100% * @return array|null * hue => 0..360 * saturation => 0.0..1.0 * lightness => 0.0..1.0 * alpha => 0.0..1.0 */ public function hsla($hue = NULL, $saturation = NULL, $lightness = NULL, $alpha = NULL) { if ($hue === NULL) { // Get the HSLA values: return array_merge($this->hsl(), array('alpha' => $this->alpha())); } // Set the HSLA values: $rgb = self::hsl2rgb($hue, $saturation, $lightness); $this->rgba($rgb['red'], $rgb['green'], $rgb['blue'], $alpha); return $this; } /** * Gets/sets all HSL values. * * @param null|float $hue * 0..360 * @param null|float|string $saturation * 0.0..1.0 or 0%..100% * @param null|float|string $lightness * 0.0..1.0 or 0%..100% * @return array|null * hue => 0..360 * saturation => 0.0..1.0 * lightness => 0.0..1.0 */ public function hsl($hue = NULL, $saturation = NULL, $lightness = NULL) { if ($hue === NULL) { // Get the HSL values: return self::rgb2hsl($this->red(), $this->green(), $this->blue()); } // Set the HSL values: $rgb = self::hsl2rgb($hue, $saturation, $lightness); $this->rgb($rgb['red'], $rgb['green'], $rgb['blue']); return $this; } /////////////////////////////////////////////////////////////////////////// // Lightness-related methods. /** * Returns true for a dark color. * * @return bool */ public function isDark() { return $this->lightness() < 0.5; } /** * Returns true for a light color. * * @return bool */ public function isLight() { return $this->lightness() >= 0.5; } /////////////////////////////////////////////////////////////////////////// // Miscellaneous static methods. /** * Returns true if the string is a hex color string. * Leading '#' is optional. Can be 6-digit or 3-digit. * * @return bool * @param string $str */ public static function isHexString($str) { $hex_digit = "[a-f0-9]"; $pattern = "/^#?($hex_digit{6}|$hex_digit{3})$/i"; return (bool) preg_match($pattern, $str); } /** * Mix two colors. * If called with only two parameters then the colors are mixed 50-50. * * @param int|string|StarColor $color1 * @param int|string|StarColor $color2 * @param float $frac1 * 0.0..1.0 Fraction of $color1 * @return StarColor */ public static function mix($color1, $color2, $frac1 = 0.5) { $color1 = self::normalizeColor($color1); $color2 = self::normalizeColor($color2); $frac1 = (float) $frac1; if ($frac1 <= 0) { return $color2; } if ($frac1 >= 1) { return $color1; } // Get the red, green, blue and alpha parts of the new color: $frac2 = 1 - $frac1; $red = round(($color1->red() * $frac1) + ($color2->red() * $frac2)); $green = round(($color1->green() * $frac1) + ($color2->green() * $frac2)); $blue = round(($color1->blue() * $frac1) + ($color2->blue() * $frac2)); $alpha = ($color1->alpha() * $frac1) + ($color2->alpha() * $frac2); // Create and return the mixed color: return new StarColor($red, $green, $blue, $alpha); } /** * Blend two colors. * * This method is for setting one pixel ($color1) on top of another ($color2) on an image. * @see StarImage::setPixel * * For formulas: * @see http://www.w3.org/TR/2003/REC-SVG11-20030114/masking.html#SimpleAlphaBlending * @see http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending * * @param int|string|StarColor $top_color * @param int|string|StarColor $bottom_color * @return StarColor */ public static function blend($top_color, $bottom_color) { $top_color = self::normalizeColor($top_color); $bottom_color = self::normalizeColor($bottom_color); // Calculate resultant alpha: $a1 = $top_color->alpha(); $a2 = $bottom_color->alpha(); $a3 = $a1 + $a2 * (1 - $a1); // Calculate red, green and blue components of resultant color: $rgb1 = $top_color->rgb(); $rgb2 = $bottom_color->rgb(); $rgb3 = array(); foreach ($rgb1 as $color => $value) { $rgb3[$color] = (($value * $a1) + ($rgb2[$color] * $a2 * (1 - $a1))) / $a3; } // Create and return new color: return new StarColor($rgb3['red'], $rgb3['green'], $rgb3['blue'], $a3); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Output methods: /** * Outputs the color as an RGB CSS string. * * @return string */ public function rgbString() { $red = $this->red(); $green = $this->green(); $blue = $this->blue(); return "rgb($red, $green, $blue)"; } /** * Outputs the color as an RGBA CSS string. * * @return string */ public function rgbaString() { $red = $this->red(); $green = $this->green(); $blue = $this->blue(); $alpha = round($this->alpha(), 3); return "rgba($red, $green, $blue, $alpha)"; } /** * Outputs the color as an HSL CSS string. * * @return string */ public function hslString() { $hsl = $this->hsl(); $hue = round($hsl['hue']); $saturation = round($hsl['saturation'] * 100) . '%'; $lightness = round($hsl['lightness'] * 100) . '%'; return "hsl($hue, $saturation, $lightness)"; } /** * Outputs the color as an RGBA CSS string. * * @return string */ public function hslaString() { $hsla = $this->hsla(); $hue = round($hsla['hue']); $saturation = round($hsla['saturation'] * 100) . '%'; $lightness = round($hsla['lightness'] * 100) . '%'; $alpha = round($hsla['alpha'], 3); return "hsla($hue, $saturation, $lightness, $alpha)"; } /** * Outputs the color as a 6-digit hexadecimal string, or 8-digit if alpha is included. * * @param bool $include_alpha * @param bool $include_hash * @return string */ public function hex($include_alpha = FALSE, $include_hash = TRUE) { if ($include_alpha) { $value = $this->value; $n_chars = 8; } else { $value = ($this->value >> 8) & 0xFFFFFF; $n_chars = 6; } return ($include_hash ? '#' : '') . str_pad(strtoupper(dechex($value)), $n_chars, '0', STR_PAD_LEFT); } /** * Default string representation of color is 8-digit RGBA hex string. * Not CSS compatible, but concise and informative. * * @return string */ public function __toString() { return $this->hex(TRUE, TRUE); } /** * Get the color as an informative array, with: * red * green * blue * alpha * hue * saturation * lightness * hex * * @return array */ public function toArray() { return array_merge($this->rgba(), $this->hsl(), array('hex' => $this->hex())); } ///////////////////////////////////////////////////////////////////////// // Protected static methods to normalize parameters. /** * Convert a null, int, float or string to an int between 0..255. * Used for red, green, blue. * * @static * @param null|int|float|string $value * 0..255 or 0%..100% * @return int * 0..255 */ protected static function normalizeByte($value) { // Default to 0: if ($value === NULL) { return 0; } // Look for % value: if (is_string($value) && preg_match("/^((\d*\.)?\d+)%$/", trim($value), $matches)) { $value = $matches[1] / 100 * 255; } // Convert to int: $value = (int) round((float) $value); // Clamp value: if ($value < 0) { $value = 0; } elseif ($value > 255) { $value = 255; } return $value; } /** * Convert a value to a float between 0.0 and 1.0. * Used for saturation and lightness. * * @static * @param float|string $value * 0.0..1.0 or 0%..100% * @return float * 0.0..1.0 */ protected static function normalizeFraction($value) { // Default to 1.0: if ($value === NULL) { return 1.0; } // Check for percentage: if (is_string($value) && preg_match("/^((\d*\.)?\d+)%$/", trim($value), $matches)) { $value = $matches[1] / 100; } // Convert to float: $value = (float) $value; // Clamp value: if ($value < 0) { $value = 0; } elseif ($value > 1) { $value = 1; } return $value; } /** * Convert a fractional value to a byte value. * Used for alpha. * * @static * @param float|string $value * 0.0..1.0 or 0%..100% * @return int * 0..255 */ protected static function normalizeFractionByte($value) { return round(self::normalizeFraction($value) * 255); } /** * Converts value to a float in the range 0..360. * Used for hue. * * @param int|float $value * @return float * 0..360 */ protected static function normalizeDegree($value) { // Default to 0: if ($value === NULL) { return 0; } // Convert to float: $value = (float) $value; // Shift value to valid range: if ($value < 0) { // Add multiples of 360 so it's within range: return $value + (ceil(-$value / 360) * 360); } if ($value > 360) { // Subtract multiples of 360 so it's within range: return $value - (floor($value / 360) * 360); } return $value; } /** * Converts value to a StarColor, if not one already. * Use this to avoid creating a new object if the param is already a StarColor. * * @param int|string|StarColor $color */ protected static function normalizeColor($color) { return ($color instanceof StarColor) ? $color : new StarColor($color); } ///////////////////////////////////////////////////////////////////////// // Static methods for converting between RGB, HSL and hex. /** * Convert RGB values to HSL. * * Algorithms: * @see http://www.w3.org/TR/css3-color/#hsl-color * @see http://130.113.54.154/~monger/hsl-rgb.html * @see http://en.wikipedia.org/wiki/HSL_color_space * * @param int $red * 0..255 * @param int $green * 0..255 * @param int $blue * 0..255 * @return array * hue => 0..360 * saturation => 0.0..1.0 * lightness => 0.0..1.0 */ public static function rgb2hsl($red, $green, $blue) { // Convert the red, green and blue values to fractions: $red = self::normalizeByte($red) / 255; $green = self::normalizeByte($green) / 255; $blue = self::normalizeByte($blue) / 255; // Get the min and max values: $min = min($red, $green, $blue); $max = max($red, $green, $blue); // Calculate lightness: $lightness = ($min + $max) / 2; if ($min == $max) { // Grey: $saturation = 0; $hue = 0; // Actually undefined (without hue), but 0 is standard. } else { // Calculate saturation: $d = $max - $min; if ($lightness < 0.5) { $saturation = $d / ($max + $min); } else { $saturation = $d / (2 - $max - $min); } // Calculate hue: if ($red == $max) { $hue = ($green - $blue) / $d; } elseif ($green == $max) { $hue = 2 + (($blue - $red) / $d); } else { $hue = 4 + (($red - $green) / $d); } // Convert hue to degrees: $hue *= 60; if ($hue < 0) { $hue += 360; } } return array('hue' => $hue, 'saturation' => $saturation, 'lightness' => $lightness ); } /** * Convert HSL values to RGB. * * @param float $hue * 0..360 * @param float $saturation * 0.0..1.0 or 0%..100% * @param float $lightness * 0.0..1.0 or 0%..100% * @return array * red => 0..255 * green => 0..255 * blue => 0..255 */ public static function hsl2rgb($hue, $saturation, $lightness) { // Convert values to fractions: $hue = self::normalizeDegree($hue) / 360; $saturation = self::normalizeFraction($saturation); $lightness = self::normalizeFraction($lightness); if ($saturation == 0) { // Grey: $red = $green = $blue = round($lightness * 255); } else { $m2 = ($lightness <= 0.5) ? ($lightness * ($saturation + 1)) : ($lightness + $saturation - ($lightness * $saturation)); $m1 = $lightness * 2 - $m2; $red = self::hue2rgb($m1, $m2, $hue + (1 / 3)); $green = self::hue2rgb($m1, $m2, $hue); $blue = self::hue2rgb($m1, $m2, $hue - (1 / 3)); } return array('red' => $red, 'green' => $green, 'blue' => $blue ); } /** * Protected helper function for converting HSL values to RGB. * Return value is color component 0..255. * * @param float $m1 * @param float $m2 * @param float $h * @return int * 0..255 */ protected static function hue2rgb($m1, $m2, $h) { if ($h < 0) { $h += 1; } elseif ($h > 1) { $h -= 1; } if ($h * 6 < 1) { $c = $m1 + (($m2 - $m1) * $h * 6); } elseif ($h * 2 < 1) { $c = $m2; } elseif ($h * 3 < 2) { $c = $m1 + (($m2 - $m1) * (2 / 3 - $h) * 6); } else { $c = $m1; } return round($c * 255); } /** * Convert an RGB color value to a 2-digit hex string. * * @static * @param int|string $byte * 0..255 or 0%..100% * @return string */ public static function byte2hex($byte) { $byte = self::normalizeByte($byte); return str_pad(strtoupper(dechex($byte)), 2, '0', STR_PAD_LEFT); } /** * Convert RGB values to a 6-digit hex string. * * @param int|string $red * 0..255 or 0%..100% * @param int|string $green * 0..255 or 0%..100% * @param int|string $blue * 0..255 or 0%..100% * @return string */ public static function rgb2hex($red, $green, $blue) { return self::byte2hex($red) . self::byte2hex($green) . self::byte2hex($blue); } /** * Convert 3 or 6-digit hex string to RGB values. * * @param string * @return array */ public static function hex2rgb($hex) { if (!self::isHexString($hex)) { return FALSE; } // Remove any leading # character: if ($hex[0] == '#') { $hex = substr($hex, 1); } if (strlen($hex) == 6) { // 6-digit hex string. Split string into bytes: $red = hexdec(substr($hex, 0, 2)); $green = hexdec(substr($hex, 2, 2)); $blue = hexdec(substr($hex, 4, 2)); } else { // 3-digit hex string. Double each hex digit: $red = hexdec($hex[0] . $hex[0]); $green = hexdec($hex[1] . $hex[1]); $blue = hexdec($hex[2] . $hex[2]); } return array( 'red' => $red, 'green' => $green, 'blue' => $blue, ); } ///////////////////////////////////////////////////////////////////////// // Named colors /** * Array for mapping color names to hex values. * * @var array */ protected static $colorNames = array( 'aliceblue' => 'F0F8FF', 'amethyst' => '9966CC', 'antiquewhite' => 'FAEBD7', 'aqua' => '00FFFF', 'aquamarine' => '7FFFD4', 'azure' => 'F0FFFF', 'beige' => 'F5F5DC', 'bisque' => 'FFE4C4', 'black' => '000000', 'blanchedalmond' => 'FFEBCD', 'blue' => '0000FF', 'blueviolet' => '8A2BE2', 'brown' => 'A52A2A', 'burlywood' => 'DEB887', 'cadetblue' => '5F9EA0', 'chartreuse' => '7FFF00', 'chocolate' => 'D2691E', 'coral' => 'FF7F50', 'cornflowerblue' => '6495ED', 'cornsilk' => 'FFF8DC', 'crimson' => 'DC143C', 'cyan' => '00FFFF', 'darkblue' => '00008B', 'darkcyan' => '008B8B', 'darkgoldenrod' => 'B8860B', 'darkgray' => 'A9A9A9', 'darkgreen' => '006400', 'darkgrey' => 'A9A9A9', 'darkkhaki' => 'BDB76B', 'darkmagenta' => '8B008B', 'darkolivegreen' => '556B2F', 'darkorange' => 'FF8C00', 'darkorchid' => '9932CC', 'darkred' => '8B0000', 'darksalmon' => 'E9967A', 'darkseagreen' => '8FBC8F', 'darkslateblue' => '483D8B', 'darkslategray' => '2F4F4F', 'darkslategrey' => '2F4F4F', 'darkturquoise' => '00CED1', 'darkviolet' => '9400D3', 'deeppink' => 'FF1493', 'deepskyblue' => '00BFFF', 'dimgray' => '696969', 'dimgrey' => '696969', 'dodgerblue' => '1E90FF', 'firebrick' => 'B22222', 'floralwhite' => 'FFFAF0', 'forestgreen' => '228B22', 'fuchsia' => 'FF00FF', 'gainsboro' => 'DCDCDC', 'ghostwhite' => 'F8F8FF', 'gold' => 'FFD700', 'goldenrod' => 'DAA520', 'gray' => '808080', 'green' => '008000', 'greenyellow' => 'ADFF2F', 'grey' => '808080', 'honeydew' => 'F0FFF0', 'hotpink' => 'FF69B4', 'indianred' => 'CD5C5C', 'indigo' => '4B0082', 'ivory' => 'FFFFF0', 'khaki' => 'F0E68C', 'lavender' => 'E6E6FA', 'lavenderblush' => 'FFF0F5', 'lawngreen' => '7CFC00', 'lemonchiffon' => 'FFFACD', 'lightblue' => 'ADD8E6', 'lightcoral' => 'F08080', 'lightcyan' => 'E0FFFF', 'lightgoldenrodyellow' => 'FAFAD2', 'lightgray' => 'D3D3D3', 'lightgreen' => '90EE90', 'lightgrey' => 'D3D3D3', 'lightpink' => 'FFB6C1', 'lightsalmon' => 'FFA07A', 'lightseagreen' => '20B2AA', 'lightskyblue' => '87CEFA', 'lightslategray' => '778899', 'lightslategrey' => '778899', 'lightsteelblue' => 'B0C4DE', 'lightyellow' => 'FFFFE0', 'lime' => '00FF00', 'limegreen' => '32CD32', 'linen' => 'FAF0E6', 'magenta' => 'FF00FF', 'maroon' => '800000', 'mediumaquamarine' => '66CDAA', 'mediumblue' => '0000CD', 'mediumorchid' => 'BA55D3', 'mediumpurple' => '9370DB', 'mediumseagreen' => '3CB371', 'mediumslateblue' => '7B68EE', 'mediumspringgreen' => '00FA9A', 'mediumturquoise' => '48D1CC', 'mediumvioletred' => 'C71585', 'midnightblue' => '191970', 'mintcream' => 'F5FFFA', 'mistyrose' => 'FFE4E1', 'moccasin' => 'FFE4B5', 'navajowhite' => 'FFDEAD', 'navy' => '000080', 'oldlace' => 'FDF5E6', 'olive' => '808000', 'olivedrab' => '6B8E23', 'orange' => 'FFA500', 'orangered' => 'FF4500', 'orchid' => 'DA70D6', 'palegoldenrod' => 'EEE8AA', 'palegreen' => '98FB98', 'paleturquoise' => 'AFEEEE', 'palevioletred' => 'DB7093', 'papayawhip' => 'FFEFD5', 'peachpuff' => 'FFDAB9', 'peru' => 'CD853F', 'pink' => 'FFC0CB', 'plum' => 'DDA0DD', 'powderblue' => 'B0E0E6', 'purple' => '800080', 'red' => 'FF0000', 'rosybrown' => 'BC8F8F', 'royalblue' => '4169E1', 'saddlebrown' => '8B4513', 'salmon' => 'FA8072', 'sandybrown' => 'F4A460', 'seagreen' => '2E8B57', 'seashell' => 'FFF5EE', 'sienna' => 'A0522D', 'silver' => 'C0C0C0', 'skyblue' => '87CEEB', 'slateblue' => '6A5ACD', 'slategray' => '708090', 'slategrey' => '708090', 'snow' => 'FFFAFA', 'springgreen' => '00FF7F', 'steelblue' => '4682B4', 'tan' => 'D2B48C', 'teal' => '008080', 'thistle' => 'D8BFD8', 'tomato' => 'FF6347', 'turquoise' => '40E0D0', 'violet' => 'EE82EE', 'wheat' => 'F5DEB3', 'white' => 'FFFFFF', 'whitesmoke' => 'F5F5F5', 'yellow' => 'FFFF00', 'yellowgreen' => '9ACD32', ); /** * Return the array of color names. * * @static * @return array */ public static function colorNames() { return self::$colorNames; } /** * Check if a given string is a color name. * * @static * @param string $name * @return bool */ public static function isColorName($name) { $name = strtolower($name); return isset(self::$colorNames[$name]); } /** * Convert a color name to a 6-digit hex value. * * @static * @param $name * @return bool */ private static function colorName2hex($name) { $name = strtolower($name); return isset(self::$colorNames[$name]) ? self::$colorNames[$name] : FALSE; } }