<?php |
<?php |
/** |
/** |
* |
* |
* Color values manipulation utilities. Provides methods to convert from and to |
* Color values manipulation utilities. Provides methods to convert from and to |
* Hex, RGB, HSV and HSL color representattions. |
* Hex, RGB, HSV and HSL color representattions. |
* |
* |
* Several color conversion logic are based on pseudo-code from |
* Several color conversion logic are based on pseudo-code from |
* http://www.easyrgb.com/math.php |
* http://www.easyrgb.com/math.php |
* |
* |
* @category Lux |
* @category Lux |
* |
* |
* @package Lux_Color |
* @package Lux_Color |
* |
* |
* @author Rodrigo Moraes <rodrigo.moraes@gmail.com> |
* @author Rodrigo Moraes <rodrigo.moraes@gmail.com> |
* |
* |
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
* |
* |
* @version $Id$ |
* @version $Id$ |
* |
* |
*/ |
*/ |
class Lux_Color |
class Lux_Color |
{ |
{ |
/** |
/** |
* |
* |
* Converts hexadecimal colors to RGB. |
* Converts hexadecimal colors to RGB. |
* |
* |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* |
* |
* @return array RGB values: 0 => R, 1 => G, 2 => B |
* @return array RGB values: 0 => R, 1 => G, 2 => B |
* |
* |
*/ |
*/ |
public function hex2rgb($hex) |
public function hex2rgb($hex) |
{ |
{ |
// Remove #. |
// Remove #. |
if (strpos($hex, '#') === 0) { |
if (strpos($hex, '#') === 0) { |
$hex = substr($hex, 1); |
$hex = substr($hex, 1); |
} |
} |
|
|
if (strlen($hex) == 3) { |
if (strlen($hex) == 3) { |
$hex .= $hex; |
$hex .= $hex; |
} |
} |
|
|
if (strlen($hex) != 6) { |
if (strlen($hex) != 6) { |
return false; |
return false; |
} |
} |
|
|
// Convert each tuple to decimal. |
// Convert each tuple to decimal. |
$r = hexdec(substr($hex, 0, 2)); |
$r = hexdec(substr($hex, 0, 2)); |
$g = hexdec(substr($hex, 2, 2)); |
$g = hexdec(substr($hex, 2, 2)); |
$b = hexdec(substr($hex, 4, 2)); |
$b = hexdec(substr($hex, 4, 2)); |
|
|
return array($r, $g, $b); |
return array($r, $g, $b); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts hexadecimal colors to HSV. |
* Converts hexadecimal colors to HSV. |
* |
* |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* |
* |
* @return array HSV values: 0 => H, 1 => S, 2 => V |
* @return array HSV values: 0 => H, 1 => S, 2 => V |
* |
* |
*/ |
*/ |
public function hex2hsv($hex) |
public function hex2hsv($hex) |
{ |
{ |
return $this->rgb2hsv($this->hex2rgb($hex)); |
return $this->rgb2hsv($this->hex2rgb($hex)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts hexadecimal colors to HSL. |
* Converts hexadecimal colors to HSL. |
* |
* |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* @param string $hex Hexadecimal value. Accepts values with 3 or 6 numbers, |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* |
* |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* |
* |
*/ |
*/ |
public function hex2hsl($hex) |
public function hex2hsl($hex) |
{ |
{ |
return $this->rgb2hsl($this->hex2rgb($hex)); |
return $this->rgb2hsl($this->hex2rgb($hex)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts RGB colors to hexadecimal. |
* Converts RGB colors to hexadecimal. |
* |
* |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* |
* |
* @return string Hexadecimal value with six digits, e.g., CCCCCC. |
* @return string Hexadecimal value with six digits, e.g., CCCCCC. |
* |
* |
*/ |
*/ |
public function rgb2hex($rgb) |
public function rgb2hex($rgb) |
{ |
{ |
if(count($rgb) < 3) { |
if(count($rgb) < 3) { |
return false; |
return false; |
} |
} |
|
|
list($r, $g, $b) = $rgb; |
list($r, $g, $b) = $rgb; |
|
|
// From php.net. |
// From php.net. |
$r = 0x10000 * max(0, min(255, $r)); |
$r = 0x10000 * max(0, min(255, $r)); |
$g = 0x100 * max(0, min(255, $g)); |
$g = 0x100 * max(0, min(255, $g)); |
$b = max(0, min(255, $b)); |
$b = max(0, min(255, $b)); |
|
|
return strtoupper(str_pad(dechex($r + $g + $b), 6, 0, STR_PAD_LEFT)); |
return strtoupper(str_pad(dechex($r + $g + $b), 6, 0, STR_PAD_LEFT)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts RGB to HSV. |
* Converts RGB to HSV. |
* |
* |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* |
* |
* @return array HSV values: 0 => H, 1 => S, 2 => V |
* @return array HSV values: 0 => H, 1 => S, 2 => V |
* |
* |
*/ |
*/ |
public function rgb2hsv($rgb) |
public function rgb2hsv($rgb) |
{ |
{ |
// RGB values = 0 ÷ 255 |
// RGB values = 0 ÷ 255 |
$var_R = ($rgb[0] / 255); |
$var_R = ($rgb[0] / 255); |
$var_G = ($rgb[1] / 255); |
$var_G = ($rgb[1] / 255); |
$var_B = ($rgb[2] / 255); |
$var_B = ($rgb[2] / 255); |
|
|
// Min. value of RGB |
// Min. value of RGB |
$var_Min = min($var_R, $var_G, $var_B); |
$var_Min = min($var_R, $var_G, $var_B); |
|
|
// Max. value of RGB |
// Max. value of RGB |
$var_Max = max($var_R, $var_G, $var_B); |
$var_Max = max($var_R, $var_G, $var_B); |
|
|
// Delta RGB value |
// Delta RGB value |
$del_Max = $var_Max - $var_Min; |
$del_Max = $var_Max - $var_Min; |
|
|
$V = $var_Max; |
$V = $var_Max; |
|
|
// This is a gray, no chroma... |
// This is a gray, no chroma... |
if ( $del_Max == 0 ) { |
if ( $del_Max == 0 ) { |
// HSV results = 0 ÷ 1 |
// HSV results = 0 ÷ 1 |
$H = 0; |
$H = 0; |
$S = 0; |
$S = 0; |
} else { |
} else { |
// Chromatic data... |
// Chromatic data... |
$S = $del_Max / $var_Max; |
$S = $del_Max / $var_Max; |
|
|
$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max; |
$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max; |
$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max; |
$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max; |
$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max; |
$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max; |
|
|
if ($var_R == $var_Max) { |
if ($var_R == $var_Max) { |
$H = $del_B - $del_G; |
$H = $del_B - $del_G; |
} else if ($var_G == $var_Max) { |
} else if ($var_G == $var_Max) { |
$H = (1 / 3) + $del_R - $del_B; |
$H = (1 / 3) + $del_R - $del_B; |
} else if ($var_B == $var_Max) { |
} else if ($var_B == $var_Max) { |
$H = (2 / 3) + $del_G - $del_R; |
$H = (2 / 3) + $del_G - $del_R; |
} |
} |
|
|
if ($H < 0) { |
if ($H < 0) { |
$H += 1; |
$H += 1; |
} |
} |
if ($H > 1) { |
if ($H > 1) { |
$H -= 1; |
$H -= 1; |
} |
} |
} |
} |
|
|
// Returns agnostic values. |
// Returns agnostic values. |
// Range will depend on the application: e.g. $H*360, $S*100, $V*100. |
// Range will depend on the application: e.g. $H*360, $S*100, $V*100. |
return array($H, $S, $V); |
return array($H, $S, $V); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts RGB to HSL. |
* Converts RGB to HSL. |
* |
* |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* @param array $rgb RGB values: 0 => R, 1 => G, 2 => B |
* |
* |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* |
* |
*/ |
*/ |
public function rgb2hsl($rgb) |
public function rgb2hsl($rgb) |
{ |
{ |
// Where RGB values = 0 ÷ 255. |
// Where RGB values = 0 ÷ 255. |
$var_R = $rgb[0] / 255; |
$var_R = $rgb[0] / 255; |
$var_G = $rgb[1] / 255; |
$var_G = $rgb[1] / 255; |
$var_B = $rgb[2] / 255; |
$var_B = $rgb[2] / 255; |
|
|
// Min. value of RGB |
// Min. value of RGB |
$var_Min = min($var_R, $var_G, $var_B); |
$var_Min = min($var_R, $var_G, $var_B); |
// Max. value of RGB |
// Max. value of RGB |
$var_Max = max($var_R, $var_G, $var_B); |
$var_Max = max($var_R, $var_G, $var_B); |
// Delta RGB value |
// Delta RGB value |
$del_Max = $var_Max - $var_Min; |
$del_Max = $var_Max - $var_Min; |
|
|
$L = ($var_Max + $var_Min) / 2; |
$L = ($var_Max + $var_Min) / 2; |
|
|
if ( $del_Max == 0 ) { |
if ( $del_Max == 0 ) { |
// This is a gray, no chroma... |
// This is a gray, no chroma... |
// HSL results = 0 ÷ 1 |
// HSL results = 0 ÷ 1 |
$H = 0; |
$H = 0; |
$S = 0; |
$S = 0; |
} else { |
} else { |
// Chromatic data... |
// Chromatic data... |
if ($L < 0.5) { |
if ($L < 0.5) { |
$S = $del_Max / ($var_Max + $var_Min); |
$S = $del_Max / ($var_Max + $var_Min); |
} else { |
} else { |
$S = $del_Max / ( 2 - $var_Max - $var_Min ); |
$S = $del_Max / ( 2 - $var_Max - $var_Min ); |
} |
} |
|
|
$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max; |
$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max; |
$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max; |
$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max; |
$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max; |
$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max; |
|
|
if ($var_R == $var_Max) { |
if ($var_R == $var_Max) { |
$H = $del_B - $del_G; |
$H = $del_B - $del_G; |
} else if ($var_G == $var_Max) { |
} else if ($var_G == $var_Max) { |
$H = ( 1 / 3 ) + $del_R - $del_B; |
$H = ( 1 / 3 ) + $del_R - $del_B; |
} else if ($var_B == $var_Max) { |
} else if ($var_B == $var_Max) { |
$H = ( 2 / 3 ) + $del_G - $del_R; |
$H = ( 2 / 3 ) + $del_G - $del_R; |
} |
} |
|
|
if ($H < 0) { |
if ($H < 0) { |
$H += 1; |
$H += 1; |
} |
} |
if ($H > 1) { |
if ($H > 1) { |
$H -= 1; |
$H -= 1; |
} |
} |
} |
} |
|
|
return array($H, $S, $L); |
return array($H, $S, $L); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts HSV colors to hexadecimal. |
* Converts HSV colors to hexadecimal. |
* |
* |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* |
* |
* @return string Hexadecimal value with six digits, e.g., CCCCCC. |
* @return string Hexadecimal value with six digits, e.g., CCCCCC. |
* |
* |
*/ |
*/ |
public function hsv2hex($hsv) |
public function hsv2hex($hsv) |
{ |
{ |
return $this->rgb2hex($this->hsv2rgb($hsv)); |
return $this->rgb2hex($this->hsv2rgb($hsv)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts HSV to RGB. |
* Converts HSV to RGB. |
* |
* |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* |
* |
* @return array RGB values: 0 => R, 1 => G, 2 => B |
* @return array RGB values: 0 => R, 1 => G, 2 => B |
* |
* |
*/ |
*/ |
public function hsv2rgb($hsv) |
public function hsv2rgb($hsv) |
{ |
{ |
$H = $hsv[0]; |
$H = $hsv[0]; |
$S = $hsv[1]; |
$S = $hsv[1]; |
$V = $hsv[2]; |
$V = $hsv[2]; |
|
|
// HSV values = 0 ÷ 1 |
// HSV values = 0 ÷ 1 |
if ($S == 0) { |
if ($S == 0) { |
$R = $V * 255; |
$R = $V * 255; |
$G = $V * 255; |
$G = $V * 255; |
$B = $V * 255; |
$B = $V * 255; |
} else { |
} else { |
$var_h = $H * 6; |
$var_h = $H * 6; |
// H must be < 1 |
// H must be < 1 |
if ( $var_h == 6 ) { |
if ( $var_h == 6 ) { |
$var_h = 0; |
$var_h = 0; |
} |
} |
// Or ... $var_i = floor( $var_h ) |
// Or ... $var_i = floor( $var_h ) |
$var_i = floor( $var_h ); |
$var_i = floor( $var_h ); |
$var_1 = $V * ( 1 - $S ); |
$var_1 = $V * ( 1 - $S ); |
$var_2 = $V * ( 1 - $S * ( $var_h - $var_i ) ); |
$var_2 = $V * ( 1 - $S * ( $var_h - $var_i ) ); |
$var_3 = $V * ( 1 - $S * ( 1 - ( $var_h - $var_i ) ) ); |
$var_3 = $V * ( 1 - $S * ( 1 - ( $var_h - $var_i ) ) ); |
|
|
switch($var_i) { |
switch($var_i) { |
case 0: |
case 0: |
$var_r = $V; |
$var_r = $V; |
$var_g = $var_3; |
$var_g = $var_3; |
$var_b = $var_1; |
$var_b = $var_1; |
break; |
break; |
case 1: |
case 1: |
$var_r = $var_2; |
$var_r = $var_2; |
$var_g = $V; |
$var_g = $V; |
$var_b = $var_1; |
$var_b = $var_1; |
break; |
break; |
case 2: |
case 2: |
$var_r = $var_1; |
$var_r = $var_1; |
$var_g = $V; |
$var_g = $V; |
$var_b = $var_3; |
$var_b = $var_3; |
break; |
break; |
case 3: |
case 3: |
$var_r = $var_1; |
$var_r = $var_1; |
$var_g = $var_2; |
$var_g = $var_2; |
$var_b = $V; |
$var_b = $V; |
break; |
break; |
case 4: |
case 4: |
$var_r = $var_3; |
$var_r = $var_3; |
$var_g = $var_1; |
$var_g = $var_1; |
$var_b = $V; |
$var_b = $V; |
break; |
break; |
default: |
default: |
$var_r = $V; |
$var_r = $V; |
$var_g = $var_1; |
$var_g = $var_1; |
$var_b = $var_2; |
$var_b = $var_2; |
} |
} |
|
|
//RGB results = 0 ÷ 255 |
//RGB results = 0 ÷ 255 |
$R = $var_r * 255; |
$R = $var_r * 255; |
$G = $var_g * 255; |
$G = $var_g * 255; |
$B = $var_b * 255; |
$B = $var_b * 255; |
} |
} |
|
|
return array($R, $G, $B); |
return array($R, $G, $B); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts HSV colors to HSL. |
* Converts HSV colors to HSL. |
* |
* |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* @param array $hsv HSV values: 0 => H, 1 => S, 2 => V |
* |
* |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* @return array HSL values: 0 => H, 1 => S, 2 => L |
* |
* |
*/ |
*/ |
public function hsv2hsl($hsv) |
public function hsv2hsl($hsv) |
{ |
{ |
return $this->rgb2hsl($this->hsv2rgb($hsv)); |
return $this->rgb2hsl($this->hsv2rgb($hsv)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts hexadecimal colors to HSL. |
* Converts hexadecimal colors to HSL. |
* |
* |
* @param array $hsl HSL values: 0 => H, 1 => S, 2 => L |
* @param array $hsl HSL values: 0 => H, 1 => S, 2 => L |
* |
* |
* @return string Hexadecimal value. Accepts values with 3 or 6 numbers, |
* @return string Hexadecimal value. Accepts values with 3 or 6 numbers, |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* with or without #, e.g., CCC, #CCC, CCCCCC or #CCCCCC. |
* |
* |
*/ |
*/ |
public function hsl2hex($hsl) |
public function hsl2hex($hsl) |
{ |
{ |
return $this->rgb2hex($this->hsl2rgb($hsl)); |
return $this->rgb2hex($this->hsl2rgb($hsl)); |
} |
} |
|
|
/** |
/** |
* |
* |
* Converts HSL to RGB. |
* Converts HSL to RGB. |
* |
* |
* @param array $hsv HSL values: 0 => H, 1 => S, 2 => L |
* @param array $hsv HSL values: 0 => H, 1 => S, 2 => L |
* |
* |