File: /home/wbwebdes/domains/support.wb-webdesign.com/private_html/inc/tecnick/Color/Web.php
<?php
/**
* Web.php
*
* @since 2015-02-21
* @category Library
* @package Color
* @author Nicola Asuni <[email protected]>
* @copyright 2015-2015 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-color
*
* This file is part of tc-lib-color software library.
*/
namespace Com\Tecnick\Color;
use \Com\Tecnick\Color\Exception as ColorException;
/**
* Com\Tecnick\Color\Web
*
* Web Color class
*
* @since 2015-02-21
* @category Library
* @package Color
* @author Nicola Asuni <[email protected]>
* @copyright 2015-2015 Nicola Asuni - Tecnick.com LTD
* @license http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-color
*/
class Web extends \Com\Tecnick\Color\Css
{
/**
* Array of WEB safe colors #RRGGBBAA
*
* @var array
*/
protected static $webhex = array(
'aliceblue' => 'f0f8ffff',
'antiquewhite' => 'faebd7ff',
'aqua' => '00ffffff',
'aquamarine' => '7fffd4ff',
'azure' => 'f0ffffff',
'beige' => 'f5f5dcff',
'bisque' => 'ffe4c4ff',
'black' => '000000ff',
'blanchedalmond' => 'ffebcdff',
'blue' => '0000ffff',
'blueviolet' => '8a2be2ff',
'brown' => 'a52a2aff',
'burlywood' => 'deb887ff',
'cadetblue' => '5f9ea0ff',
'chartreuse' => '7fff00ff',
'chocolate' => 'd2691eff',
'coral' => 'ff7f50ff',
'cornflowerblue' => '6495edff',
'cornsilk' => 'fff8dcff',
'crimson' => 'dc143cff',
'cyan' => '00ffffff',
'darkblue' => '00008bff',
'darkcyan' => '008b8bff',
'darkgoldenrod' => 'b8860bff',
'dkgray' => 'a9a9a9ff',
'darkgray' => 'a9a9a9ff',
'darkgrey' => 'a9a9a9ff',
'darkgreen' => '006400ff',
'darkkhaki' => 'bdb76bff',
'darkmagenta' => '8b008bff',
'darkolivegreen' => '556b2fff',
'darkorange' => 'ff8c00ff',
'darkorchid' => '9932ccff',
'darkred' => '8b0000ff',
'darksalmon' => 'e9967aff',
'darkseagreen' => '8fbc8fff',
'darkslateblue' => '483d8bff',
'darkslategray' => '2f4f4fff',
'darkslategrey' => '2f4f4fff',
'darkturquoise' => '00ced1ff',
'darkviolet' => '9400d3ff',
'deeppink' => 'ff1493ff',
'deepskyblue' => '00bfffff',
'dimgray' => '696969ff',
'dimgrey' => '696969ff',
'dodgerblue' => '1e90ffff',
'firebrick' => 'b22222ff',
'floralwhite' => 'fffaf0ff',
'forestgreen' => '228b22ff',
'fuchsia' => 'ff00ffff',
'gainsboro' => 'dcdcdcff',
'ghostwhite' => 'f8f8ffff',
'gold' => 'ffd700ff',
'goldenrod' => 'daa520ff',
'gray' => '808080ff',
'grey' => '808080ff',
'green' => '008000ff',
'greenyellow' => 'adff2fff',
'honeydew' => 'f0fff0ff',
'hotpink' => 'ff69b4ff',
'indianred' => 'cd5c5cff',
'indigo' => '4b0082ff',
'ivory' => 'fffff0ff',
'khaki' => 'f0e68cff',
'lavender' => 'e6e6faff',
'lavenderblush' => 'fff0f5ff',
'lawngreen' => '7cfc00ff',
'lemonchiffon' => 'fffacdff',
'lightblue' => 'add8e6ff',
'lightcoral' => 'f08080ff',
'lightcyan' => 'e0ffffff',
'lightgoldenrodyellow' => 'fafad2ff',
'ltgray' => 'd3d3d3ff',
'lightgray' => 'd3d3d3ff',
'lightgrey' => 'd3d3d3ff',
'lightgreen' => '90ee90ff',
'lightpink' => 'ffb6c1ff',
'lightsalmon' => 'ffa07aff',
'lightseagreen' => '20b2aaff',
'lightskyblue' => '87cefaff',
'lightslategray' => '778899ff',
'lightslategrey' => '778899ff',
'lightsteelblue' => 'b0c4deff',
'lightyellow' => 'ffffe0ff',
'lime' => '00ff00ff',
'limegreen' => '32cd32ff',
'linen' => 'faf0e6ff',
'magenta' => 'ff00ffff',
'maroon' => '800000ff',
'mediumaquamarine' => '66cdaaff',
'mediumblue' => '0000cdff',
'mediumorchid' => 'ba55d3ff',
'mediumpurple' => '9370d8ff',
'mediumseagreen' => '3cb371ff',
'mediumslateblue' => '7b68eeff',
'mediumspringgreen' => '00fa9aff',
'mediumturquoise' => '48d1ccff',
'mediumvioletred' => 'c71585ff',
'midnightblue' => '191970ff',
'mintcream' => 'f5fffaff',
'mistyrose' => 'ffe4e1ff',
'moccasin' => 'ffe4b5ff',
'navajowhite' => 'ffdeadff',
'navy' => '000080ff',
'oldlace' => 'fdf5e6ff',
'olive' => '808000ff',
'olivedrab' => '6b8e23ff',
'orange' => 'ffa500ff',
'orangered' => 'ff4500ff',
'orchid' => 'da70d6ff',
'palegoldenrod' => 'eee8aaff',
'palegreen' => '98fb98ff',
'paleturquoise' => 'afeeeeff',
'palevioletred' => 'd87093ff',
'papayawhip' => 'ffefd5ff',
'peachpuff' => 'ffdab9ff',
'peru' => 'cd853fff',
'pink' => 'ffc0cbff',
'plum' => 'dda0ddff',
'powderblue' => 'b0e0e6ff',
'purple' => '800080ff',
'red' => 'ff0000ff',
'rosybrown' => 'bc8f8fff',
'royalblue' => '4169e1ff',
'saddlebrown' => '8b4513ff',
'salmon' => 'fa8072ff',
'sandybrown' => 'f4a460ff',
'seagreen' => '2e8b57ff',
'seashell' => 'fff5eeff',
'sienna' => 'a0522dff',
'silver' => 'c0c0c0ff',
'skyblue' => '87ceebff',
'slateblue' => '6a5acdff',
'slategray' => '708090ff',
'slategrey' => '708090ff',
'snow' => 'fffafaff',
'springgreen' => '00ff7fff',
'steelblue' => '4682b4ff',
'tan' => 'd2b48cff',
'teal' => '008080ff',
'thistle' => 'd8bfd8ff',
'tomato' => 'ff6347ff',
'turquoise' => '40e0d0ff',
'violet' => 'ee82eeff',
'wheat' => 'f5deb3ff',
'white' => 'ffffffff',
'whitesmoke' => 'f5f5f5ff',
'yellow' => 'ffff00ff',
'yellowgreen' => '9acd32ff'
);
/**
* Get the color map (name => hexhash)
*
* @return array
*/
public function getMap()
{
return self::$webhex;
}
/**
* Get the color hexadecimal hash code from name
*
* @param string $name Name of the color to search (e.g.: 'turquoise')
*
* @return string color hexadecimal code (e.g.: '40e0d0ff')
*
* @throws ColorException if the color is not found
*/
public function getHexFromName($name)
{
$name = strtolower($name);
if (($dotpos = strpos($name, '.')) !== false) {
// remove parent name (i.e.: color.green)
$name = substr($name, ($dotpos + 1));
}
if (empty(self::$webhex[$name])) {
throw new ColorException('unable to find the color hex for the name: '.$name);
}
return self::$webhex[$name];
}
/**
* Get the color name code from hexadecimal hash
*
* @param string $hex hexadecimal color hash (i.e. #RRGGBBAA)
*
* @return string color name
*
* @throws ColorException if the color is not found
*/
public function getNameFromHex($hex)
{
$name = array_search($this->extractHexCode($hex), self::$webhex, true);
if ($name === false) {
throw new ColorException('unable to find the color name for the hex code: '.$hex);
}
return $name;
}
/**
* Extract the hexadecimal code from the input string and add the alpha channel if missing
*
* @param string $hex string containing the hexadecimal color hash (i.e. #RGB, #RGBA, #RRGGBB, #RRGGBBAA)
*
* @return string the hash code (e.g.: '40e0d0')
*
* @throws ColorException if the hash is not found or has an invalid format
*/
public function extractHexCode($hex)
{
if (preg_match('/^[#]?([0-9a-f]{3,8})$/', strtolower($hex), $match) !== 1) {
throw new ColorException('unable to extract the color hash: '.$hex);
}
$hex = $match[1];
switch (strlen($hex)) {
case 3:
return $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2].'ff';
case 4:
return $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2].$hex[3].$hex[3];
case 6:
return $hex.'ff';
}
return $hex;
}
/**
* Get the RGB color object from hexadecimal hash
*
* @param string $hex hexadecimal color hash (i.e. #RGB, #RGBA, #RRGGBB, #RRGGBBAA)
*
* @return array with keys ('red', 'green', 'blue', 'alpha')
*
* @throws ColorException if the color is not found
*/
public function getRgbObjFromHex($hex)
{
return new \Com\Tecnick\Color\Model\Rgb(
$this->getHexArray(
$this->extractHexCode($hex)
)
);
}
/**
* Get the RGB color object from color name
*
* @param string $name Color name
*
* @return \Com\Tecnick\Color\Model\Rgb object
*
* @throws ColorException if the color is not found
*/
public function getRgbObjFromName($name)
{
return new \Com\Tecnick\Color\Model\Rgb(
$this->getHexArray(
$this->getHexFromName($name)
)
);
}
/**
* Get the RGB array from hexadecimal hash
*
* @param string $hex hexadecimal color hash (i.e. RRGGBBAA)
*
* @return array with keys ('red', 'green', 'blue', 'alpha')
*/
private function getHexArray($hex)
{
return array(
'red' => (hexdec(substr($hex, 0, 2)) / 255),
'green' => (hexdec(substr($hex, 2, 2)) / 255),
'blue' => (hexdec(substr($hex, 4, 2)) / 255),
'alpha' => (hexdec(substr($hex, 6, 2)) / 255),
);
}
/**
* Get the normalized integer value from [0..$max] to [0..1]
*
* @param float $value Value to convert
* @param int $max Max input value
*
* @return float value [0..1]
*/
public function normalizeValue($value, $max)
{
if (strpos($value, '%') !== false) {
return max(0, min(1, (floatval($value) / 100)));
}
return max(0, min(1, (floatval($value) / $max)));
}
/**
* Parse the input color string and return the correspondent color Object
*
* @param string $color String containing web color definition
*
* @return \Com\Tecnick\Color\Model or null in case of transparent color
*
* @throws ColorException in case of error
*/
public function getColorObj($color)
{
$color = preg_replace('/[\s]*/', '', strtolower($color));
if (empty($color) || (strpos($color, 'transparent') !== false)) {
return null;
}
if ($color[0] === '#') {
return $this->getRgbObjFromHex($color);
}
if ($color[0] === '[') {
return $this->getColorObjFromJs($color);
}
$rex = '/^(t|g|rgba|rgb|hsla|hsl|cmyka|cmyk)[\(]/';
if (preg_match($rex, $color, $col) === 1) {
return $this->getColorObjFromCss($col[1], $color);
}
return $this->getRgbObjFromName($color);
}
/**
* Get the square of the distance between 2 RGB points
*
* @param array $cola First color as RGB array
* @param array $colb Second color as RGB array
*
* @return float
*/
public function getRgbSquareDistance($cola, $colb)
{
return (pow(($cola['red'] - $colb['red']), 2)
+ pow(($cola['green'] - $colb['green']), 2)
+ pow(($cola['blue'] - $colb['blue']), 2));
}
/**
* Get the name of the closest web color
*
* @param array $col Color as RGB array (keys: 'red', 'green', 'blue')
*
* @return string
*/
public function getClosestWebColor($col)
{
$color = '';
$mindist = 3; // = 1^2 + 1^2 + 1^2
foreach (self::$webhex as $name => $hex) {
$dist = $this->getRgbSquareDistance($col, $this->getHexArray($hex));
if ($dist <= $mindist) {
$mindist = $dist;
$color = $name;
}
}
return $color;
}
}