1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: namespace Com\Tecnick\Color;
17:
18: use \Com\Tecnick\Color\Exception as ColorException;
19:
20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: class Web extends \Com\Tecnick\Color\Css
34: {
35: 36: 37: 38: 39:
40: protected static $webhex = array(
41: 'aliceblue' => 'f0f8ffff',
42: 'antiquewhite' => 'faebd7ff',
43: 'aqua' => '00ffffff',
44: 'aquamarine' => '7fffd4ff',
45: 'azure' => 'f0ffffff',
46: 'beige' => 'f5f5dcff',
47: 'bisque' => 'ffe4c4ff',
48: 'black' => '000000ff',
49: 'blanchedalmond' => 'ffebcdff',
50: 'blue' => '0000ffff',
51: 'blueviolet' => '8a2be2ff',
52: 'brown' => 'a52a2aff',
53: 'burlywood' => 'deb887ff',
54: 'cadetblue' => '5f9ea0ff',
55: 'chartreuse' => '7fff00ff',
56: 'chocolate' => 'd2691eff',
57: 'coral' => 'ff7f50ff',
58: 'cornflowerblue' => '6495edff',
59: 'cornsilk' => 'fff8dcff',
60: 'crimson' => 'dc143cff',
61: 'cyan' => '00ffffff',
62: 'darkblue' => '00008bff',
63: 'darkcyan' => '008b8bff',
64: 'darkgoldenrod' => 'b8860bff',
65: 'dkgray' => 'a9a9a9ff',
66: 'darkgray' => 'a9a9a9ff',
67: 'darkgrey' => 'a9a9a9ff',
68: 'darkgreen' => '006400ff',
69: 'darkkhaki' => 'bdb76bff',
70: 'darkmagenta' => '8b008bff',
71: 'darkolivegreen' => '556b2fff',
72: 'darkorange' => 'ff8c00ff',
73: 'darkorchid' => '9932ccff',
74: 'darkred' => '8b0000ff',
75: 'darksalmon' => 'e9967aff',
76: 'darkseagreen' => '8fbc8fff',
77: 'darkslateblue' => '483d8bff',
78: 'darkslategray' => '2f4f4fff',
79: 'darkslategrey' => '2f4f4fff',
80: 'darkturquoise' => '00ced1ff',
81: 'darkviolet' => '9400d3ff',
82: 'deeppink' => 'ff1493ff',
83: 'deepskyblue' => '00bfffff',
84: 'dimgray' => '696969ff',
85: 'dimgrey' => '696969ff',
86: 'dodgerblue' => '1e90ffff',
87: 'firebrick' => 'b22222ff',
88: 'floralwhite' => 'fffaf0ff',
89: 'forestgreen' => '228b22ff',
90: 'fuchsia' => 'ff00ffff',
91: 'gainsboro' => 'dcdcdcff',
92: 'ghostwhite' => 'f8f8ffff',
93: 'gold' => 'ffd700ff',
94: 'goldenrod' => 'daa520ff',
95: 'gray' => '808080ff',
96: 'grey' => '808080ff',
97: 'green' => '008000ff',
98: 'greenyellow' => 'adff2fff',
99: 'honeydew' => 'f0fff0ff',
100: 'hotpink' => 'ff69b4ff',
101: 'indianred' => 'cd5c5cff',
102: 'indigo' => '4b0082ff',
103: 'ivory' => 'fffff0ff',
104: 'khaki' => 'f0e68cff',
105: 'lavender' => 'e6e6faff',
106: 'lavenderblush' => 'fff0f5ff',
107: 'lawngreen' => '7cfc00ff',
108: 'lemonchiffon' => 'fffacdff',
109: 'lightblue' => 'add8e6ff',
110: 'lightcoral' => 'f08080ff',
111: 'lightcyan' => 'e0ffffff',
112: 'lightgoldenrodyellow' => 'fafad2ff',
113: 'ltgray' => 'd3d3d3ff',
114: 'lightgray' => 'd3d3d3ff',
115: 'lightgrey' => 'd3d3d3ff',
116: 'lightgreen' => '90ee90ff',
117: 'lightpink' => 'ffb6c1ff',
118: 'lightsalmon' => 'ffa07aff',
119: 'lightseagreen' => '20b2aaff',
120: 'lightskyblue' => '87cefaff',
121: 'lightslategray' => '778899ff',
122: 'lightslategrey' => '778899ff',
123: 'lightsteelblue' => 'b0c4deff',
124: 'lightyellow' => 'ffffe0ff',
125: 'lime' => '00ff00ff',
126: 'limegreen' => '32cd32ff',
127: 'linen' => 'faf0e6ff',
128: 'magenta' => 'ff00ffff',
129: 'maroon' => '800000ff',
130: 'mediumaquamarine' => '66cdaaff',
131: 'mediumblue' => '0000cdff',
132: 'mediumorchid' => 'ba55d3ff',
133: 'mediumpurple' => '9370d8ff',
134: 'mediumseagreen' => '3cb371ff',
135: 'mediumslateblue' => '7b68eeff',
136: 'mediumspringgreen' => '00fa9aff',
137: 'mediumturquoise' => '48d1ccff',
138: 'mediumvioletred' => 'c71585ff',
139: 'midnightblue' => '191970ff',
140: 'mintcream' => 'f5fffaff',
141: 'mistyrose' => 'ffe4e1ff',
142: 'moccasin' => 'ffe4b5ff',
143: 'navajowhite' => 'ffdeadff',
144: 'navy' => '000080ff',
145: 'oldlace' => 'fdf5e6ff',
146: 'olive' => '808000ff',
147: 'olivedrab' => '6b8e23ff',
148: 'orange' => 'ffa500ff',
149: 'orangered' => 'ff4500ff',
150: 'orchid' => 'da70d6ff',
151: 'palegoldenrod' => 'eee8aaff',
152: 'palegreen' => '98fb98ff',
153: 'paleturquoise' => 'afeeeeff',
154: 'palevioletred' => 'd87093ff',
155: 'papayawhip' => 'ffefd5ff',
156: 'peachpuff' => 'ffdab9ff',
157: 'peru' => 'cd853fff',
158: 'pink' => 'ffc0cbff',
159: 'plum' => 'dda0ddff',
160: 'powderblue' => 'b0e0e6ff',
161: 'purple' => '800080ff',
162: 'red' => 'ff0000ff',
163: 'rosybrown' => 'bc8f8fff',
164: 'royalblue' => '4169e1ff',
165: 'saddlebrown' => '8b4513ff',
166: 'salmon' => 'fa8072ff',
167: 'sandybrown' => 'f4a460ff',
168: 'seagreen' => '2e8b57ff',
169: 'seashell' => 'fff5eeff',
170: 'sienna' => 'a0522dff',
171: 'silver' => 'c0c0c0ff',
172: 'skyblue' => '87ceebff',
173: 'slateblue' => '6a5acdff',
174: 'slategray' => '708090ff',
175: 'slategrey' => '708090ff',
176: 'snow' => 'fffafaff',
177: 'springgreen' => '00ff7fff',
178: 'steelblue' => '4682b4ff',
179: 'tan' => 'd2b48cff',
180: 'teal' => '008080ff',
181: 'thistle' => 'd8bfd8ff',
182: 'tomato' => 'ff6347ff',
183: 'turquoise' => '40e0d0ff',
184: 'violet' => 'ee82eeff',
185: 'wheat' => 'f5deb3ff',
186: 'white' => 'ffffffff',
187: 'whitesmoke' => 'f5f5f5ff',
188: 'yellow' => 'ffff00ff',
189: 'yellowgreen' => '9acd32ff'
190: );
191:
192: 193: 194: 195: 196:
197: public function getMap()
198: {
199: return self::$webhex;
200: }
201:
202: 203: 204: 205: 206: 207: 208: 209: 210:
211: public function getHexFromName($name)
212: {
213: $name = strtolower($name);
214: if (($dotpos = strpos($name, '.')) !== false) {
215:
216: $name = substr($name, ($dotpos + 1));
217: }
218: if (empty(self::$webhex[$name])) {
219: throw new ColorException('unable to find the color hex for the name: '.$name);
220: }
221: return self::$webhex[$name];
222: }
223:
224: 225: 226: 227: 228: 229: 230: 231: 232:
233: public function getNameFromHex($hex)
234: {
235: $name = array_search($this->extractHexCode($hex), self::$webhex, true);
236: if ($name === false) {
237: throw new ColorException('unable to find the color name for the hex code: '.$hex);
238: }
239: return $name;
240: }
241:
242: 243: 244: 245: 246: 247: 248: 249: 250:
251: public function extractHexCode($hex)
252: {
253: if (preg_match('/^[#]?([0-9a-f]{3,8})$/', strtolower($hex), $match) !== 1) {
254: throw new ColorException('unable to extract the color hash: '.$hex);
255: }
256: $hex = $match[1];
257: switch (strlen($hex)) {
258: case 3:
259: return $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2].'ff';
260: case 4:
261: return $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2].$hex[3].$hex[3];
262: case 6:
263: return $hex.'ff';
264: }
265: return $hex;
266: }
267:
268: 269: 270: 271: 272: 273: 274: 275: 276:
277: public function getRgbObjFromHex($hex)
278: {
279: return new \Com\Tecnick\Color\Model\Rgb(
280: $this->getHexArray(
281: $this->extractHexCode($hex)
282: )
283: );
284: }
285:
286: 287: 288: 289: 290: 291: 292: 293: 294:
295: public function getRgbObjFromName($name)
296: {
297: return new \Com\Tecnick\Color\Model\Rgb(
298: $this->getHexArray(
299: $this->getHexFromName($name)
300: )
301: );
302: }
303:
304: 305: 306: 307: 308: 309: 310:
311: private function getHexArray($hex)
312: {
313: return array(
314: 'red' => (hexdec(substr($hex, 0, 2)) / 255),
315: 'green' => (hexdec(substr($hex, 2, 2)) / 255),
316: 'blue' => (hexdec(substr($hex, 4, 2)) / 255),
317: 'alpha' => (hexdec(substr($hex, 6, 2)) / 255),
318: );
319: }
320:
321: 322: 323: 324: 325: 326: 327: 328:
329: public function normalizeValue($value, $max)
330: {
331: if (strpos($value, '%') !== false) {
332: return max(0, min(1, (floatval($value) / 100)));
333: }
334: return max(0, min(1, (floatval($value) / $max)));
335: }
336:
337: 338: 339: 340: 341: 342: 343: 344: 345:
346: public function getColorObj($color)
347: {
348: $color = preg_replace('/[\s]*/', '', strtolower($color));
349: if (empty($color) || (strpos($color, 'transparent') !== false)) {
350: return null;
351: }
352: if ($color[0] === '#') {
353: return $this->getRgbObjFromHex($color);
354: }
355: if ($color[0] === '[') {
356: return $this->getColorObjFromJs($color);
357: }
358: $rex = '/^(t|g|rgba|rgb|hsla|hsl|cmyka|cmyk)[\(]/';
359: if (preg_match($rex, $color, $col) === 1) {
360: return $this->getColorObjFromCss($col[1], $color);
361: }
362: return $this->getRgbObjFromName($color);
363: }
364:
365: 366: 367: 368: 369: 370: 371: 372:
373: public function getRgbSquareDistance($cola, $colb)
374: {
375: return (pow(($cola['red'] - $colb['red']), 2)
376: + pow(($cola['green'] - $colb['green']), 2)
377: + pow(($cola['blue'] - $colb['blue']), 2));
378: }
379:
380: 381: 382: 383: 384: 385: 386:
387: public function getClosestWebColor($col)
388: {
389: $color = '';
390: $mindist = 3;
391: foreach (self::$webhex as $name => $hex) {
392: $dist = $this->getRgbSquareDistance($col, $this->getHexArray($hex));
393: if ($dist <= $mindist) {
394: $mindist = $dist;
395: $color = $name;
396: }
397: }
398: return $color;
399: }
400: }
401: