|
1
|
|
|
<?php namespace XoopsModules\Pedigree; |
|
2
|
|
|
|
|
3
|
|
|
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* Color.php is the implementation of ImageColor. |
|
7
|
|
|
* |
|
8
|
|
|
* PHP versions 4 and 5 |
|
9
|
|
|
* |
|
10
|
|
|
* LICENSE: This source file is subject to version 3.0 of the PHP license |
|
11
|
|
|
* that is available through the world-wide-web at the following URI: |
|
12
|
|
|
* http://www.php.net/license/3_0.txt. If you did not receive a copy of |
|
13
|
|
|
* the PHP License and are unable to obtain it through the web, please |
|
14
|
|
|
* send a note to [email protected] so we can mail you a copy immediately. |
|
15
|
|
|
* |
|
16
|
|
|
* @category Image |
|
17
|
|
|
* @package ImageColor |
|
18
|
|
|
* @author Jason Lotito <[email protected]> |
|
19
|
|
|
* @author Andrew Morton <[email protected]> |
|
20
|
|
|
* @copyright 2003-2005 The PHP Group |
|
21
|
|
|
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
|
22
|
|
|
* @version 1.1 2006/04/30 |
|
23
|
|
|
* @link http://pear.php.net/package/ImageColor |
|
24
|
|
|
*/ |
|
25
|
|
|
|
|
26
|
|
|
/** |
|
27
|
|
|
* ImageColor handles color conversion and mixing. |
|
28
|
|
|
* |
|
29
|
|
|
* The class is quick, simple to use, and does its job fairly well but it's got |
|
30
|
|
|
* some code smells: |
|
31
|
|
|
* - Call setColors() for some functions but not others. |
|
32
|
|
|
* - Different functions expect different color formats. setColors() only |
|
33
|
|
|
* accepts hex while allocateColor() will accept named or hex (provided the |
|
34
|
|
|
* hex ones start with the # character). |
|
35
|
|
|
* - Some conversions go in only one direction, ie HSV->RGB but no RGB->HSV. |
|
36
|
|
|
* I'm going to try to straighten out some of this but I'll be hard to do so |
|
37
|
|
|
* without breaking backwards compatibility. |
|
38
|
|
|
* |
|
39
|
|
|
* @category Image |
|
40
|
|
|
* @package ImageColor |
|
41
|
|
|
* @author Jason Lotito <[email protected]> |
|
42
|
|
|
* @author Andrew Morton <[email protected]> |
|
43
|
|
|
* @copyright 2003-2005 The PHP Group |
|
44
|
|
|
* @license http://www.php.net/license/3_0.txt PHP License 3.0 |
|
45
|
|
|
* @version Release: 0.1.2 |
|
46
|
|
|
* @link http://pear.php.net/package/ImageColor |
|
47
|
|
|
*/ |
|
48
|
|
|
|
|
49
|
|
|
use XoopsModules\Pedigree; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Class ImageColor |
|
53
|
|
|
*/ |
|
54
|
|
|
class ImageColor |
|
55
|
|
|
{ |
|
56
|
|
|
/** |
|
57
|
|
|
* First color that the class handles for ranges and mixes. |
|
58
|
|
|
* |
|
59
|
|
|
* @var array |
|
60
|
|
|
* @access public |
|
61
|
|
|
* @see setColors() |
|
62
|
|
|
*/ |
|
63
|
|
|
public $color1 = []; |
|
64
|
|
|
|
|
65
|
|
|
/** |
|
66
|
|
|
* Second color that the class handles for ranges and mixes. |
|
67
|
|
|
* |
|
68
|
|
|
* @var array |
|
69
|
|
|
* @access public |
|
70
|
|
|
* @see setColors() |
|
71
|
|
|
*/ |
|
72
|
|
|
public $color2 = []; |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* Boolean value for determining whether colors outputted should be limited |
|
76
|
|
|
* to the web safe pallet or not. |
|
77
|
|
|
* |
|
78
|
|
|
* @var boolean |
|
79
|
|
|
* @access private |
|
80
|
|
|
* @see setWebSafe() |
|
81
|
|
|
*/ |
|
82
|
|
|
private $websafeb = false; |
|
83
|
|
|
|
|
84
|
|
|
/** |
|
85
|
|
|
* Mix two colors together by finding their average. If the colors are not |
|
86
|
|
|
* passed as parameters, the class's colors will be mixed instead. |
|
87
|
|
|
* |
|
88
|
|
|
* @param bool|string $col1 The first color you want to mix |
|
89
|
|
|
* @param bool|string $col2 The second color you want to mix |
|
90
|
|
|
* |
|
91
|
|
|
* @return string The mixed color. |
|
92
|
|
|
* @access public |
|
93
|
|
|
* @author Jason Lotito <[email protected]> |
|
94
|
|
|
* @uses setInternalColors() to assign the colors if any are passed to the |
|
95
|
|
|
* class. |
|
96
|
|
|
*/ |
|
97
|
|
|
public function mixColors($col1 = false, $col2 = false) |
|
98
|
|
|
{ |
|
99
|
|
|
if ($col1) { |
|
100
|
|
|
$this->setInternalColors($col1, $col2); |
|
|
|
|
|
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
// after finding the average, it will be a float. add 0.5 and then |
|
104
|
|
|
// cast to an integer to properly round it to an integer. |
|
105
|
|
|
$color3[0] = (int)((($this->color1[0] + $this->color2[0]) / 2) + 0.5); |
|
|
|
|
|
|
106
|
|
|
$color3[1] = (int)((($this->color1[1] + $this->color2[1]) / 2) + 0.5); |
|
107
|
|
|
$color3[2] = (int)((($this->color1[2] + $this->color2[2]) / 2) + 0.5); |
|
108
|
|
|
|
|
109
|
|
|
if ($this->websafeb) { |
|
110
|
|
|
array_walk($color3, '_makeWebSafe'); |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
return $this->rgb2hex($color3); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* Determines whether colors the returned by this class will be rounded to |
|
118
|
|
|
* the nearest web safe value. |
|
119
|
|
|
* |
|
120
|
|
|
* @param boolean $bool Indicates if colors should be limited to the |
|
121
|
|
|
* websafe pallet. |
|
122
|
|
|
* |
|
123
|
|
|
* @return void |
|
124
|
|
|
* @access public |
|
125
|
|
|
* @author Jason Lotito <[email protected]> |
|
126
|
|
|
*/ |
|
127
|
|
|
public function setWebSafe($bool = true) |
|
128
|
|
|
{ |
|
129
|
|
|
$this->websafeb = (boolean)$bool; |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
/** |
|
133
|
|
|
* Set the two colors this class uses for mixing and ranges. |
|
134
|
|
|
* |
|
135
|
|
|
* @param string $col1 The first color in hex format |
|
136
|
|
|
* @param string $col2 The second color in hex format |
|
137
|
|
|
* |
|
138
|
|
|
* @return void |
|
139
|
|
|
* @access public |
|
140
|
|
|
* @author Jason Lotito <[email protected]> |
|
141
|
|
|
*/ |
|
142
|
|
|
public function setColors($col1, $col2) |
|
143
|
|
|
{ |
|
144
|
|
|
$this->setInternalColors($col1, $col2); |
|
145
|
|
|
} |
|
146
|
|
|
|
|
147
|
|
|
/** |
|
148
|
|
|
* Get the range of colors between the class's two colors, given a degree. |
|
149
|
|
|
* |
|
150
|
|
|
* @param integer $degrees How large a 'step' we should take between the |
|
151
|
|
|
* colors. |
|
152
|
|
|
* |
|
153
|
|
|
* @return array Returns an array of hex strings, one element for each |
|
154
|
|
|
* color. |
|
155
|
|
|
* @access public |
|
156
|
|
|
* @author Jason Lotito <[email protected]> |
|
157
|
|
|
* @todo Allow for degrees for individual parts of the colors. |
|
158
|
|
|
*/ |
|
159
|
|
|
public function getRange($degrees = 2) |
|
160
|
|
|
{ |
|
161
|
|
|
if (0 == $degrees) { |
|
162
|
|
|
$degrees = 1; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
// The degrees give us how much we should advance each color at each |
|
166
|
|
|
// phase of the loop. This way, the advance is equal throughout all |
|
167
|
|
|
// the colors. |
|
168
|
|
|
|
|
169
|
|
|
$red_steps = ($this->color2[0] - $this->color1[0]) / $degrees; |
|
170
|
|
|
$green_steps = ($this->color2[1] - $this->color1[1]) / $degrees; |
|
171
|
|
|
$blue_steps = ($this->color2[2] - $this->color1[2]) / $degrees; |
|
172
|
|
|
|
|
173
|
|
|
$allcolors = []; |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* The loop stops once any color has gone beyond the end color. |
|
177
|
|
|
*/ |
|
178
|
|
|
|
|
179
|
|
|
// Loop through all the degrees between the colors |
|
180
|
|
|
for ($x = 0; $x < $degrees; ++$x) { |
|
181
|
|
|
$col[0] = $red_steps * $x; |
|
182
|
|
|
$col[1] = $green_steps * $x; |
|
183
|
|
|
$col[2] = $blue_steps * $x; |
|
184
|
|
|
|
|
185
|
|
|
// Loop through each R, G, and B |
|
186
|
|
|
for ($i = 0; $i < 3; ++$i) { |
|
187
|
|
|
$partcolor = $this->color1[$i] + $col[$i]; |
|
188
|
|
|
// If the color is less than 256 |
|
189
|
|
|
if ($partcolor < 256) { |
|
190
|
|
|
// Makes sure the colors is not less than 0 |
|
191
|
|
|
if ($partcolor > -1) { |
|
192
|
|
|
$newcolor[$i] = $partcolor; |
|
193
|
|
|
} else { |
|
194
|
|
|
$newcolor[$i] = 0; |
|
195
|
|
|
} |
|
196
|
|
|
// Color was greater than 255 |
|
197
|
|
|
} else { |
|
198
|
|
|
$newcolor[$i] = 255; |
|
199
|
|
|
} |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
if ($this->websafeb) { |
|
203
|
|
|
array_walk($newcolor, '_makeWebSafe'); |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
$allcolors[] = $this->rgb2hex($newcolor); |
|
|
|
|
|
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
return $allcolors; |
|
210
|
|
|
} |
|
211
|
|
|
|
|
212
|
|
|
/** |
|
213
|
|
|
* Change the lightness of the class's two colors. |
|
214
|
|
|
* |
|
215
|
|
|
* @param integer $degree The degree of the change. Positive values |
|
216
|
|
|
* lighten the color while negative values will darken it. |
|
217
|
|
|
* |
|
218
|
|
|
* @return void |
|
219
|
|
|
* @access public |
|
220
|
|
|
* @author Jason Lotito <[email protected]> |
|
221
|
|
|
* @uses ImageColor::$color1 as an input and return value. |
|
222
|
|
|
* @uses ImageColor::$color2 as an input and return value. |
|
223
|
|
|
*/ |
|
224
|
|
|
public function changeLightness($degree = 10) |
|
225
|
|
|
{ |
|
226
|
|
|
$color1 =& $this->color1; |
|
227
|
|
|
$color2 =& $this->color2; |
|
228
|
|
|
|
|
229
|
|
|
for ($x = 0; $x < 3; ++$x) { |
|
230
|
|
|
if (($color1[$x] + $degree) < 256) { |
|
231
|
|
|
if (($color1[$x] + $degree) > -1) { |
|
232
|
|
|
$color1[$x] += $degree; |
|
233
|
|
|
} else { |
|
234
|
|
|
$color1[$x] = 0; |
|
235
|
|
|
} |
|
236
|
|
|
} else { |
|
237
|
|
|
$color1[$x] = 255; |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
if (($color2[$x] + $degree) < 256) { |
|
241
|
|
|
if (($color2[$x] + $degree) > -1) { |
|
242
|
|
|
$color2[$x] += $degree; |
|
243
|
|
|
} else { |
|
244
|
|
|
$color2[$x] = 0; |
|
245
|
|
|
} |
|
246
|
|
|
} else { |
|
247
|
|
|
$color2[$x] = 255; |
|
248
|
|
|
} |
|
249
|
|
|
} |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
/** |
|
253
|
|
|
* Determine if a light or dark text color would be more readable on a |
|
254
|
|
|
* background of a given color. This is determined by the G(reen) value of |
|
255
|
|
|
* RGB. You can change the dark and the light colors from their default |
|
256
|
|
|
* black and white. |
|
257
|
|
|
* |
|
258
|
|
|
* @param string $color The hex color to analyze |
|
259
|
|
|
* @param string $light The light color value to return if we should |
|
260
|
|
|
* have light text. |
|
261
|
|
|
* @param string $dark The dark color value to return if we should have |
|
262
|
|
|
* dark text. |
|
263
|
|
|
* |
|
264
|
|
|
* @return string The light or dark value which would make the text most |
|
265
|
|
|
* readable. |
|
266
|
|
|
* @access public |
|
267
|
|
|
* @static |
|
268
|
|
|
* @author Jason Lotito <[email protected]> |
|
269
|
|
|
*/ |
|
270
|
|
|
public function getTextColor($color, $light = '#FFFFFF', $dark = '#000000') |
|
271
|
|
|
{ |
|
272
|
|
|
$color = $this->splitColor($color); |
|
273
|
|
|
if ($color[1] > hexdec('66')) { |
|
274
|
|
|
return $dark; |
|
275
|
|
|
} else { |
|
276
|
|
|
return $light; |
|
277
|
|
|
} |
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
/** |
|
281
|
|
|
* Internal method to set the colors. |
|
282
|
|
|
* |
|
283
|
|
|
* @param string $col1 First color, either a name or hex value |
|
284
|
|
|
* @param string $col2 Second color, either a name or hex value |
|
285
|
|
|
* |
|
286
|
|
|
* @return void |
|
287
|
|
|
* @access private |
|
288
|
|
|
* @author Jason Lotito <[email protected]> |
|
289
|
|
|
*/ |
|
290
|
|
|
private function setInternalColors($col1, $col2) |
|
291
|
|
|
{ |
|
292
|
|
|
if ($col1) { |
|
293
|
|
|
$this->color1 = $this->splitColor($col1); |
|
294
|
|
|
} |
|
295
|
|
|
if ($col2) { |
|
296
|
|
|
$this->color2 = $this->splitColor($col2); |
|
297
|
|
|
} |
|
298
|
|
|
} |
|
299
|
|
|
|
|
300
|
|
|
/** |
|
301
|
|
|
* Given a color, properly split it up into a 3 element RGB array. |
|
302
|
|
|
* |
|
303
|
|
|
* @param string $color The color. |
|
304
|
|
|
* |
|
305
|
|
|
* @return array A three element RGB array. |
|
306
|
|
|
* @access private |
|
307
|
|
|
* @static |
|
308
|
|
|
* @author Jason Lotito <[email protected]> |
|
309
|
|
|
*/ |
|
310
|
|
|
private function splitColor($color) |
|
311
|
|
|
{ |
|
312
|
|
|
$color = str_replace('#', '', $color); |
|
313
|
|
|
$c[] = hexdec(substr($color, 0, 2)); |
|
|
|
|
|
|
314
|
|
|
$c[] = hexdec(substr($color, 2, 2)); |
|
315
|
|
|
$c[] = hexdec(substr($color, 4, 2)); |
|
316
|
|
|
|
|
317
|
|
|
return $c; |
|
318
|
|
|
} |
|
319
|
|
|
|
|
320
|
|
|
/** |
|
321
|
|
|
* This is deprecated. Use rgb2hex() instead. |
|
322
|
|
|
* |
|
323
|
|
|
* @access private |
|
324
|
|
|
* @deprecated Function deprecated after 1.0.1 |
|
325
|
|
|
* @see rgb2hex(). |
|
326
|
|
|
* |
|
327
|
|
|
* @param $color |
|
328
|
|
|
* |
|
329
|
|
|
* @return string |
|
330
|
|
|
*/ |
|
331
|
|
|
private function returnColor($color) |
|
|
|
|
|
|
332
|
|
|
{ |
|
333
|
|
|
return $this->rgb2hex($color); |
|
334
|
|
|
} |
|
335
|
|
|
|
|
336
|
|
|
/** |
|
337
|
|
|
* Convert an RGB array to a hex string. |
|
338
|
|
|
* |
|
339
|
|
|
* @param array $color 3 element RGB array. |
|
340
|
|
|
* |
|
341
|
|
|
* @return string Hex color string. |
|
342
|
|
|
* @access public |
|
343
|
|
|
* @static |
|
344
|
|
|
* @author Jason Lotito <[email protected]> |
|
345
|
|
|
* @see hex2rgb() |
|
346
|
|
|
*/ |
|
347
|
|
|
public function rgb2hex($color) |
|
348
|
|
|
{ |
|
349
|
|
|
return sprintf('%02X%02X%02X', $color[0], $color[1], $color[2]); |
|
350
|
|
|
} |
|
351
|
|
|
|
|
352
|
|
|
/** |
|
353
|
|
|
* Convert a hex color string into an RGB array. An extra fourth element |
|
354
|
|
|
* will be returned with the original hex value. |
|
355
|
|
|
* |
|
356
|
|
|
* @param string $hex Hex color string. |
|
357
|
|
|
* |
|
358
|
|
|
* @return array RGB color array with an extra 'hex' element containing |
|
359
|
|
|
* the original hex string. |
|
360
|
|
|
* @access public |
|
361
|
|
|
* @static |
|
362
|
|
|
* @author Jason Lotito <[email protected]> |
|
363
|
|
|
* @see rgb2hex() |
|
364
|
|
|
*/ |
|
365
|
|
|
public function hex2rgb($hex) |
|
366
|
|
|
{ |
|
367
|
|
|
$return = $this->splitColor($hex); |
|
368
|
|
|
$return['hex'] = $hex; |
|
369
|
|
|
|
|
370
|
|
|
return $return; |
|
371
|
|
|
} |
|
372
|
|
|
|
|
373
|
|
|
/** |
|
374
|
|
|
* Convert an HSV (Hue, Saturation, Brightness) value to RGB. |
|
375
|
|
|
* |
|
376
|
|
|
* @param integer $h Hue |
|
377
|
|
|
* @param integer $s Saturation |
|
378
|
|
|
* @param integer $v Brightness |
|
379
|
|
|
* |
|
380
|
|
|
* @return array RGB array. |
|
381
|
|
|
* @access public |
|
382
|
|
|
* @static |
|
383
|
|
|
* @author Jason Lotito <[email protected]> |
|
384
|
|
|
* @uses hsv2hex() to convert the HSV value to Hex. |
|
385
|
|
|
* @uses hex2rgb() to convert the Hex value to RGB. |
|
386
|
|
|
*/ |
|
387
|
|
|
public function hsv2rgb($h, $s, $v) |
|
388
|
|
|
{ |
|
389
|
|
|
return $this->hex2rgb($this->hsv2hex($h, $s, $v)); |
|
390
|
|
|
} |
|
391
|
|
|
|
|
392
|
|
|
/** |
|
393
|
|
|
* Convert HSV (Hue, Saturation, Brightness) to a hex color string. |
|
394
|
|
|
* |
|
395
|
|
|
* Originally written by Jurgen Schwietering. Integrated into the class by |
|
396
|
|
|
* Jason Lotito. |
|
397
|
|
|
* |
|
398
|
|
|
* @param integer $h Hue |
|
399
|
|
|
* @param integer $s Saturation |
|
400
|
|
|
* @param integer $v Brightness |
|
401
|
|
|
* |
|
402
|
|
|
* @return string The hex string. |
|
403
|
|
|
* @access public |
|
404
|
|
|
* @static |
|
405
|
|
|
* @author Jurgen Schwietering <[email protected]> |
|
406
|
|
|
* @uses rgb2hex() to convert the return value to a hex string. |
|
407
|
|
|
*/ |
|
408
|
|
|
public function hsv2hex($h, $s, $v) |
|
409
|
|
|
{ |
|
410
|
|
|
$s /= 256.0; |
|
411
|
|
|
$v /= 256.0; |
|
412
|
|
|
if (0.0 == $s) { |
|
413
|
|
|
$r = $g = $b = $v; |
|
|
|
|
|
|
414
|
|
|
|
|
415
|
|
|
return ''; |
|
416
|
|
|
} else { |
|
417
|
|
|
$h = $h / 256.0 * 6.0; |
|
418
|
|
|
$i = floor($h); |
|
419
|
|
|
$f = $h - $i; |
|
420
|
|
|
|
|
421
|
|
|
$v *= 256.0; |
|
422
|
|
|
$p = (integer)($v * (1.0 - $s)); |
|
423
|
|
|
$q = (integer)($v * (1.0 - $s * $f)); |
|
424
|
|
|
$t = (integer)($v * (1.0 - $s * (1.0 - $f))); |
|
425
|
|
|
switch ($i) { |
|
426
|
|
|
case 0: |
|
427
|
|
|
$r = $v; |
|
428
|
|
|
$g = $t; |
|
429
|
|
|
$b = $p; |
|
430
|
|
|
break; |
|
431
|
|
|
|
|
432
|
|
|
case 1: |
|
433
|
|
|
$r = $q; |
|
434
|
|
|
$g = $v; |
|
435
|
|
|
$b = $p; |
|
436
|
|
|
break; |
|
437
|
|
|
|
|
438
|
|
|
case 2: |
|
439
|
|
|
$r = $p; |
|
440
|
|
|
$g = $v; |
|
441
|
|
|
$b = $t; |
|
442
|
|
|
break; |
|
443
|
|
|
|
|
444
|
|
|
case 3: |
|
445
|
|
|
$r = $p; |
|
446
|
|
|
$g = $q; |
|
447
|
|
|
$b = $v; |
|
448
|
|
|
break; |
|
449
|
|
|
|
|
450
|
|
|
case 4: |
|
451
|
|
|
$r = $t; |
|
452
|
|
|
$g = $p; |
|
453
|
|
|
$b = $v; |
|
454
|
|
|
break; |
|
455
|
|
|
|
|
456
|
|
|
default: |
|
457
|
|
|
$r = $v; |
|
458
|
|
|
$g = $p; |
|
459
|
|
|
$b = $q; |
|
460
|
|
|
break; |
|
461
|
|
|
} |
|
462
|
|
|
} |
|
463
|
|
|
|
|
464
|
|
|
return $this->rgb2hex([$r, $g, $b]); |
|
465
|
|
|
} |
|
466
|
|
|
|
|
467
|
|
|
/** |
|
468
|
|
|
* Allocates a color in the given image. |
|
469
|
|
|
* |
|
470
|
|
|
* User defined color specifications get translated into an array of RGB |
|
471
|
|
|
* values. |
|
472
|
|
|
* |
|
473
|
|
|
* @param resource $img Image handle |
|
474
|
|
|
* @param string|array $color Name or hex string or an RGB array. |
|
475
|
|
|
* |
|
476
|
|
|
* @return bool Image color handle. |
|
477
|
|
|
* @access public |
|
478
|
|
|
* @static |
|
479
|
|
|
* @uses imagefilledarc() to allocate the color. |
|
480
|
|
|
* @uses color2RGB() to parse the color into RGB values. |
|
481
|
|
|
*/ |
|
482
|
|
|
public function allocateColor(&$img, $color) |
|
483
|
|
|
{ |
|
484
|
|
|
$color = $this->color2RGB($color); |
|
|
|
|
|
|
485
|
|
|
|
|
486
|
|
|
return imagefilledarc($img, $color[0], $color[1], $color[2]); |
|
|
|
|
|
|
487
|
|
|
} |
|
488
|
|
|
|
|
489
|
|
|
/** |
|
490
|
|
|
* Convert a named or hex color string to an RGB array. If the color begins |
|
491
|
|
|
* with the # character it will be treated as a hex value. Everything else |
|
492
|
|
|
* will be treated as a named color. If the named color is not known, black |
|
493
|
|
|
* will be returned. |
|
494
|
|
|
* |
|
495
|
|
|
* @param string $color |
|
496
|
|
|
* |
|
497
|
|
|
* @return array RGB color |
|
498
|
|
|
* @access public |
|
499
|
|
|
* @static |
|
500
|
|
|
* @author Laurent Laville <[email protected]> |
|
501
|
|
|
* @uses hex2rgb() to convert colors begining with the # character. |
|
502
|
|
|
* @uses namedColor2RGB() to convert everything not starting with a #. |
|
503
|
|
|
*/ |
|
504
|
|
|
public function color2RGB($color) |
|
505
|
|
|
{ |
|
506
|
|
|
$c = []; |
|
507
|
|
|
|
|
508
|
|
|
if ('#' === $color{0}) { |
|
509
|
|
|
$c = $this->hex2rgb($color); |
|
510
|
|
|
} else { |
|
511
|
|
|
$c = $this->namedColor2RGB($color); |
|
512
|
|
|
} |
|
513
|
|
|
|
|
514
|
|
|
return $c; |
|
515
|
|
|
} |
|
516
|
|
|
|
|
517
|
|
|
/** |
|
518
|
|
|
* Convert a named color to an RGB array. If the color is unknown black |
|
519
|
|
|
* is returned. |
|
520
|
|
|
* |
|
521
|
|
|
* @param string $color Case insensitive color name. |
|
522
|
|
|
* |
|
523
|
|
|
* @return array RGB color array. If the color was unknown, the result |
|
524
|
|
|
* will be black. |
|
525
|
|
|
* @access public |
|
526
|
|
|
* @static |
|
527
|
|
|
* @author Sebastian Bergmann <[email protected]> |
|
528
|
|
|
*/ |
|
529
|
|
|
public function namedColor2RGB($color) |
|
530
|
|
|
{ |
|
531
|
|
|
static $colornames; |
|
532
|
|
|
|
|
533
|
|
|
if (!isset($colornames)) { |
|
534
|
|
|
$colornames = [ |
|
535
|
|
|
'aliceblue' => [240, 248, 255], |
|
536
|
|
|
'antiquewhite' => [250, 235, 215], |
|
537
|
|
|
'aqua' => [0, 255, 255], |
|
538
|
|
|
'aquamarine' => [127, 255, 212], |
|
539
|
|
|
'azure' => [240, 255, 255], |
|
540
|
|
|
'beige' => [245, 245, 220], |
|
541
|
|
|
'bisque' => [255, 228, 196], |
|
542
|
|
|
'black' => [0, 0, 0], |
|
543
|
|
|
'blanchedalmond' => [255, 235, 205], |
|
544
|
|
|
'blue' => [0, 0, 255], |
|
545
|
|
|
'blueviolet' => [138, 43, 226], |
|
546
|
|
|
'brown' => [165, 42, 42], |
|
547
|
|
|
'burlywood' => [222, 184, 135], |
|
548
|
|
|
'cadetblue' => [95, 158, 160], |
|
549
|
|
|
'chartreuse' => [127, 255, 0], |
|
550
|
|
|
'chocolate' => [210, 105, 30], |
|
551
|
|
|
'coral' => [255, 127, 80], |
|
552
|
|
|
'cornflowerblue' => [100, 149, 237], |
|
553
|
|
|
'cornsilk' => [255, 248, 220], |
|
554
|
|
|
'crimson' => [220, 20, 60], |
|
555
|
|
|
'cyan' => [0, 255, 255], |
|
556
|
|
|
'darkblue' => [0, 0, 13], |
|
557
|
|
|
'darkcyan' => [0, 139, 139], |
|
558
|
|
|
'darkgoldenrod' => [184, 134, 11], |
|
559
|
|
|
'darkgray' => [169, 169, 169], |
|
560
|
|
|
'darkgreen' => [0, 100, 0], |
|
561
|
|
|
'darkkhaki' => [189, 183, 107], |
|
562
|
|
|
'darkmagenta' => [139, 0, 139], |
|
563
|
|
|
'darkolivegreen' => [85, 107, 47], |
|
564
|
|
|
'darkorange' => [255, 140, 0], |
|
565
|
|
|
'darkorchid' => [153, 50, 204], |
|
566
|
|
|
'darkred' => [139, 0, 0], |
|
567
|
|
|
'darksalmon' => [233, 150, 122], |
|
568
|
|
|
'darkseagreen' => [143, 188, 143], |
|
569
|
|
|
'darkslateblue' => [72, 61, 139], |
|
570
|
|
|
'darkslategray' => [47, 79, 79], |
|
571
|
|
|
'darkturquoise' => [0, 206, 209], |
|
572
|
|
|
'darkviolet' => [148, 0, 211], |
|
573
|
|
|
'deeppink' => [255, 20, 147], |
|
574
|
|
|
'deepskyblue' => [0, 191, 255], |
|
575
|
|
|
'dimgray' => [105, 105, 105], |
|
576
|
|
|
'dodgerblue' => [30, 144, 255], |
|
577
|
|
|
'firebrick' => [178, 34, 34], |
|
578
|
|
|
'floralwhite' => [255, 250, 240], |
|
579
|
|
|
'forestgreen' => [34, 139, 34], |
|
580
|
|
|
'fuchsia' => [255, 0, 255], |
|
581
|
|
|
'gainsboro' => [220, 220, 220], |
|
582
|
|
|
'ghostwhite' => [248, 248, 255], |
|
583
|
|
|
'gold' => [255, 215, 0], |
|
584
|
|
|
'goldenrod' => [218, 165, 32], |
|
585
|
|
|
'gray' => [128, 128, 128], |
|
586
|
|
|
'green' => [0, 128, 0], |
|
587
|
|
|
'greenyellow' => [173, 255, 47], |
|
588
|
|
|
'honeydew' => [240, 255, 240], |
|
589
|
|
|
'hotpink' => [255, 105, 180], |
|
590
|
|
|
'indianred' => [205, 92, 92], |
|
591
|
|
|
'indigo' => [75, 0, 130], |
|
592
|
|
|
'ivory' => [255, 255, 240], |
|
593
|
|
|
'khaki' => [240, 230, 140], |
|
594
|
|
|
'lavender' => [230, 230, 250], |
|
595
|
|
|
'lavenderblush' => [255, 240, 245], |
|
596
|
|
|
'lawngreen' => [124, 252, 0], |
|
597
|
|
|
'lemonchiffon' => [255, 250, 205], |
|
598
|
|
|
'lightblue' => [173, 216, 230], |
|
599
|
|
|
'lightcoral' => [240, 128, 128], |
|
600
|
|
|
'lightcyan' => [224, 255, 255], |
|
601
|
|
|
'lightgoldenrodyellow' => [250, 250, 210], |
|
602
|
|
|
'lightgreen' => [144, 238, 144], |
|
603
|
|
|
'lightgrey' => [211, 211, 211], |
|
604
|
|
|
'lightpink' => [255, 182, 193], |
|
605
|
|
|
'lightsalmon' => [255, 160, 122], |
|
606
|
|
|
'lightseagreen' => [32, 178, 170], |
|
607
|
|
|
'lightskyblue' => [135, 206, 250], |
|
608
|
|
|
'lightslategray' => [119, 136, 153], |
|
609
|
|
|
'lightsteelblue' => [176, 196, 222], |
|
610
|
|
|
'lightyellow' => [255, 255, 224], |
|
611
|
|
|
'lime' => [0, 255, 0], |
|
612
|
|
|
'limegreen' => [50, 205, 50], |
|
613
|
|
|
'linen' => [250, 240, 230], |
|
614
|
|
|
'magenta' => [255, 0, 255], |
|
615
|
|
|
'maroon' => [128, 0, 0], |
|
616
|
|
|
'mediumaquamarine' => [102, 205, 170], |
|
617
|
|
|
'mediumblue' => [0, 0, 205], |
|
618
|
|
|
'mediumorchid' => [186, 85, 211], |
|
619
|
|
|
'mediumpurple' => [147, 112, 219], |
|
620
|
|
|
'mediumseagreen' => [60, 179, 113], |
|
621
|
|
|
'mediumslateblue' => [123, 104, 238], |
|
622
|
|
|
'mediumspringgreen' => [0, 250, 154], |
|
623
|
|
|
'mediumturquoise' => [72, 209, 204], |
|
624
|
|
|
'mediumvioletred' => [199, 21, 133], |
|
625
|
|
|
'midnightblue' => [25, 25, 112], |
|
626
|
|
|
'mintcream' => [245, 255, 250], |
|
627
|
|
|
'mistyrose' => [255, 228, 225], |
|
628
|
|
|
'moccasin' => [255, 228, 181], |
|
629
|
|
|
'navajowhite' => [255, 222, 173], |
|
630
|
|
|
'navy' => [0, 0, 128], |
|
631
|
|
|
'oldlace' => [253, 245, 230], |
|
632
|
|
|
'olive' => [128, 128, 0], |
|
633
|
|
|
'olivedrab' => [107, 142, 35], |
|
634
|
|
|
'orange' => [255, 165, 0], |
|
635
|
|
|
'orangered' => [255, 69, 0], |
|
636
|
|
|
'orchid' => [218, 112, 214], |
|
637
|
|
|
'palegoldenrod' => [238, 232, 170], |
|
638
|
|
|
'palegreen' => [152, 251, 152], |
|
639
|
|
|
'paleturquoise' => [175, 238, 238], |
|
640
|
|
|
'palevioletred' => [219, 112, 147], |
|
641
|
|
|
'papayawhip' => [255, 239, 213], |
|
642
|
|
|
'peachpuff' => [255, 218, 185], |
|
643
|
|
|
'peru' => [205, 133, 63], |
|
644
|
|
|
'pink' => [255, 192, 203], |
|
645
|
|
|
'plum' => [221, 160, 221], |
|
646
|
|
|
'powderblue' => [176, 224, 230], |
|
647
|
|
|
'purple' => [128, 0, 128], |
|
648
|
|
|
'red' => [255, 0, 0], |
|
649
|
|
|
'rosybrown' => [188, 143, 143], |
|
650
|
|
|
'royalblue' => [65, 105, 225], |
|
651
|
|
|
'saddlebrown' => [139, 69, 19], |
|
652
|
|
|
'salmon' => [250, 128, 114], |
|
653
|
|
|
'sandybrown' => [244, 164, 96], |
|
654
|
|
|
'seagreen' => [46, 139, 87], |
|
655
|
|
|
'seashell' => [255, 245, 238], |
|
656
|
|
|
'sienna' => [160, 82, 45], |
|
657
|
|
|
'silver' => [192, 192, 192], |
|
658
|
|
|
'skyblue' => [135, 206, 235], |
|
659
|
|
|
'slateblue' => [106, 90, 205], |
|
660
|
|
|
'slategray' => [112, 128, 144], |
|
661
|
|
|
'snow' => [255, 250, 250], |
|
662
|
|
|
'springgreen' => [0, 255, 127], |
|
663
|
|
|
'steelblue' => [70, 130, 180], |
|
664
|
|
|
'tan' => [210, 180, 140], |
|
665
|
|
|
'teal' => [0, 128, 128], |
|
666
|
|
|
'thistle' => [216, 191, 216], |
|
667
|
|
|
'tomato' => [255, 99, 71], |
|
668
|
|
|
'turquoise' => [64, 224, 208], |
|
669
|
|
|
'violet' => [238, 130, 238], |
|
670
|
|
|
'wheat' => [245, 222, 179], |
|
671
|
|
|
'white' => [255, 255, 255], |
|
672
|
|
|
'whitesmoke' => [245, 245, 245], |
|
673
|
|
|
'yellow' => [255, 255, 0], |
|
674
|
|
|
'yellowgreen' => [154, 205, 50] |
|
675
|
|
|
]; |
|
676
|
|
|
} |
|
677
|
|
|
|
|
678
|
|
|
$color = strtolower($color); |
|
679
|
|
|
|
|
680
|
|
|
if (isset($colornames[$color])) { |
|
681
|
|
|
return $colornames[$color]; |
|
682
|
|
|
} |
|
683
|
|
|
|
|
684
|
|
|
return [0, 0, 0]; |
|
685
|
|
|
} |
|
686
|
|
|
|
|
687
|
|
|
/** |
|
688
|
|
|
* Convert an RGB percentage string into an RGB array. |
|
689
|
|
|
* |
|
690
|
|
|
* @param string $color Percentage color string like "50%,20%,100%". |
|
691
|
|
|
* |
|
692
|
|
|
* @return array RGB color array. |
|
693
|
|
|
* @access public |
|
694
|
|
|
* @static |
|
695
|
|
|
*/ |
|
696
|
|
|
public function percentageColor2RGB($color) |
|
697
|
|
|
{ |
|
698
|
|
|
// remove spaces |
|
699
|
|
|
$color = str_replace(' ', '', $color); |
|
700
|
|
|
// remove the percent signs |
|
701
|
|
|
$color = str_replace('%', '', $color); |
|
702
|
|
|
// split the string by commas |
|
703
|
|
|
$color = explode(',', $color); |
|
704
|
|
|
|
|
705
|
|
|
$ret = []; |
|
706
|
|
|
foreach ($color as $k => $v) { |
|
707
|
|
|
// range checks |
|
708
|
|
|
if ($v <= 0) { |
|
709
|
|
|
$ret[$k] = 0; |
|
710
|
|
|
} elseif ($v <= 100) { |
|
711
|
|
|
// add 0.5 then cast to an integer to round the value. |
|
712
|
|
|
$ret[$k] = (integer)((2.55 * $v) + 0.5); |
|
713
|
|
|
} else { |
|
714
|
|
|
$ret[$k] = 255; |
|
715
|
|
|
} |
|
716
|
|
|
} |
|
717
|
|
|
|
|
718
|
|
|
return $ret; |
|
719
|
|
|
} |
|
720
|
|
|
} |
|
721
|
|
|
|
|
722
|
|
|
// For Array Walk |
|
723
|
|
|
// {{{ |
|
724
|
|
|
/** |
|
725
|
|
|
* Function for array_walk() to round colors to the closest web safe value. |
|
726
|
|
|
* |
|
727
|
|
|
* @param integer $color One channel of an RGB color. |
|
728
|
|
|
* |
|
729
|
|
|
* @return integer The websafe equivalent of the color channel. |
|
730
|
|
|
* @author Jason Lotito <[email protected]> |
|
731
|
|
|
* @author Andrew Morton <[email protected]> |
|
732
|
|
|
* @access private |
|
733
|
|
|
* @static |
|
734
|
|
|
*/ |
|
735
|
|
|
function _makeWebSafe(&$color) |
|
736
|
|
|
{ |
|
737
|
|
|
if ($color < 0x1a) { |
|
738
|
|
|
$color = 0x00; |
|
739
|
|
|
} elseif ($color < 0x4d) { |
|
740
|
|
|
$color = 0x33; |
|
741
|
|
|
} elseif ($color < 0x80) { |
|
742
|
|
|
$color = 0x66; |
|
743
|
|
|
} elseif ($color < 0xB3) { |
|
744
|
|
|
$color = 0x99; |
|
745
|
|
|
} elseif ($color < 0xE6) { |
|
746
|
|
|
$color = 0xCC; |
|
747
|
|
|
} else { |
|
748
|
|
|
$color = 0xFF; |
|
749
|
|
|
} |
|
750
|
|
|
|
|
751
|
|
|
return $color; |
|
752
|
|
|
} |
|
753
|
|
|
// }}} |
|
754
|
|
|
|