export all
[disclosr.git] / lib / Color.php
blob:a/lib/Color.php -> blob:b/lib/Color.php
<?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
* *