1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace ICanBoogie;
13
14 class Image
15 {
16 static public function load($file, &$info)
17 {
18 if (!is_file($file))
19 {
20 throw new \Exception(sprintf('The file <q>%s</q> does not exists', $file));
21 }
22
23 $info = getimagesize($file);
24
25 if (!$info)
26 {
27 throw new \Exception(sprintf('Unable to get information from file <q>%s</q>', $file));
28 }
29
30 $mime = $info['mime'];
31 $image = false;
32
33 switch ($mime)
34 {
35 case 'image/jpeg':
36 {
37 $image = imagecreatefromjpeg($file);
38 }
39 break;
40
41 case 'image/png':
42 {
43 $image = imagecreatefrompng($file);
44 }
45 break;
46
47 case 'image/gif':
48 {
49 $image = imagecreatefromgif($file);
50 }
51 break;
52
53 default:
54 {
55 throw new \Exception(sprintf('Unsupported image type: %s', $mime));
56 }
57 break;
58 }
59
60 if (!$image)
61 {
62 throw new \Exception(sprintf('Unable to create image from %s', $file));
63 }
64
65 return $image;
66 }
67
68 const RESIZE_NONE = 'none';
69 const RESIZE_FIT = 'fit';
70 const RESIZE_FILL = 'fill';
71 const RESIZE_FIXED_HEIGHT = 'fixed-height';
72 const RESIZE_FIXED_HEIGHT_CROPPED = 'fixed-height-cropped';
73 const RESIZE_FIXED_WIDTH = 'fixed-width';
74 const RESIZE_FIXED_WIDTH_CROPPED = 'fixed-width-cropped';
75 const RESIZE_SURFACE = 'surface';
76 const RESIZE_SIMPLE = 'simple';
77 const RESIZE_CONSTRAINED = 'constrained';
78
79 80 81 82 83 84 85 86 87 88 89 90 91
92 static public function compute_final_size($w, $h, $method, $src)
93 {
94 static $same = array(self::RESIZE_FIT, self::RESIZE_FILL, self::RESIZE_FIXED_HEIGHT_CROPPED, self::RESIZE_FIXED_WIDTH_CROPPED);
95
96 if (in_array($method, $same))
97 {
98 return array($w, $h);
99 }
100
101 list($image_w, $image_h) = is_array($src) ? $src : getimagesize($src);
102
103 $final_w = $w;
104 $final_h = $h;
105
106 switch ($method)
107 {
108 case self::RESIZE_FIXED_HEIGHT:
109 {
110 $r = $image_h / $h;
111 $final_w = round($image_w / $r);
112 }
113 break;
114
115 case self::RESIZE_FIXED_WIDTH:
116 {
117 $r = $image_w / $w;
118 $final_h = round($image_h / $r);
119 }
120 break;
121
122 case self::RESIZE_SURFACE:
123 {
124 $r = sqrt(($image_w * $image_h) / ($w * $h));
125
126 $final_w = round($image_w / $r);
127 $final_h = round($image_h / $r);
128 }
129 break;
130
131 case self::RESIZE_CONSTRAINED:
132 {
133 $image_r = $image_w / $image_h;
134 $r = $w / $h;
135
136 $r = $image_r > $r ? $image_w / $w : $image_h / $h;
137
138 $final_w = round($image_w / $r);
139 $final_h = round($image_h / $r);
140 }
141 break;
142 }
143
144 return array($final_w, $final_h);
145 }
146
147 148 149 150 151 152 153 154 155 156 157
158 static public function assert_sizes($m, $w, $h)
159 {
160 switch ($m)
161 {
162 case Image::RESIZE_FIXED_WIDTH:
163 {
164 if (!$w)
165 {
166 throw new \InvalidArgumentException
167 (
168 \ICanBoogie\format('Width is required for the %method resize method.', array
169 (
170 'method' => $m
171 ))
172 );
173 }
174 }
175 break;
176
177 case Image::RESIZE_FIXED_HEIGHT:
178 {
179 if (!$h)
180 {
181 throw new \InvalidArgumentException
182 (
183 \ICanBoogie\format('Height is required for the %method resize method.', array
184 (
185 'method' => $m
186 ))
187 );
188 }
189 }
190 break;
191
192 default:
193 {
194 if (!$w || !$h)
195 {
196 throw new \InvalidArgumentException
197 (
198 \ICanBoogie\format('Both width and height are required for the %method resize method.', array
199 (
200 'method' => $m
201 ))
202 );
203 }
204 }
205 break;
206 }
207
208 return true;
209 }
210
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
227 static public function resize($source, &$t_w, &$t_h, $method, $fill_callback=null)
228 {
229
230
231
232
233 $s_x = 0;
234 $s_y = 0;
235 $s_w = imagesx($source);
236 $s_h = imagesy($source);
237
238
239
240
241
242 $d_x = 0;
243 $d_y = 0;
244 $d_w = $t_w;
245 $d_h = $t_h;
246
247
248
249
250
251 switch ($method)
252 {
253 case self::RESIZE_FIT:
254 default:
255 {
256
257
258
259
260
261
262
263
264 $s_r = $s_w / $s_h;
265 $d_r = $d_w / $d_h;
266
267 $r = $s_r > $d_r ? $s_w / $d_w : $s_h / $d_h;
268
269 $d_w = round($s_w / $r);
270 $d_h = round($s_h / $r);
271 }
272 break;
273
274 case self::RESIZE_FILL:
275 {
276
277
278
279
280
281
282
283
284
285 $s_r = $s_w / $s_h;
286 $d_r = $d_w / $d_h;
287
288 if ($s_r > $d_r)
289 {
290 $r = $s_h / $d_h;
291 $s_x += round(($s_w - $t_w * $r) / 2);
292 }
293 else
294 {
295 $r = $s_w / $d_w;
296 $s_y += round(($s_h - $t_h * $r) / 2);
297 }
298
299 $d_w = round($s_w / $r);
300 $d_h = round($s_h / $r);
301 }
302 break;
303
304 case self::RESIZE_FIXED_HEIGHT:
305 {
306
307
308
309
310
311
312
313
314 $r = $s_h / $d_h;
315
316 $d_w = round($s_w / $r);
317
318 if ($s_w > $s_h)
319 {
320 $d_h = round($s_h / $r);
321 }
322
323 $t_w = $d_w;
324 }
325 break;
326
327 case self::RESIZE_FIXED_HEIGHT_CROPPED:
328 {
329
330
331
332
333
334
335
336
337 $r = $s_h / $d_h;
338
339 $d_w = round($s_w / $r);
340
341 if ($s_w > $s_h)
342 {
343 $d_h = round($s_h / $r);
344 }
345 else
346 {
347 $t_w = $d_w;
348 }
349
350
351
352
353
354 if ($s_w > $t_w * $r)
355 {
356 $s_x += round(($s_w - $t_w * $r) / 2);
357 }
358 }
359 break;
360
361 case self::RESIZE_FIXED_WIDTH:
362 {
363
364
365
366
367
368
369
370
371 $r = $s_w / $d_w;
372
373 $d_h = round($s_h / $r);
374
375 if ($s_w < $s_h)
376 {
377 $d_w = round($s_w / $r);
378 }
379
380 $t_h = $d_h;
381 }
382 break;
383
384 case self::RESIZE_FIXED_WIDTH_CROPPED:
385 {
386
387
388
389
390
391
392
393
394 $r = $s_w / $d_w;
395
396 $d_h = round($s_h / $r);
397
398 if ($s_w > $s_h)
399 {
400 $t_h = $d_h;
401 }
402 else
403 {
404 $d_w = round($s_w / $r);
405 }
406
407
408
409
410
411 if ($s_h > $t_h * $r)
412 {
413 $s_y += round(($s_h - $t_h * $r) / 2);
414 }
415 }
416 break;
417
418 case self::RESIZE_SURFACE:
419 {
420
421
422
423
424
425
426
427
428 $r = sqrt(($s_w * $s_h) / ($t_w * $t_h));
429
430 $d_w = round($s_w / $r);
431 $d_h = round($s_h / $r);
432
433 $t_w = $d_w;
434 $t_h = $d_h;
435
436 }
437 break;
438
439 case self::RESIZE_SIMPLE:
440 {
441 $d_w = $t_w;
442 $d_h = $t_h;
443 }
444 break;
445
446 case self::RESIZE_CONSTRAINED:
447 {
448 $s_r = $s_w / $s_h;
449 $d_r = $d_w / $d_h;
450
451 $r = $s_r > $d_r ? $s_w / $d_w : $s_h / $d_h;
452
453 $d_w = round($s_w / $r);
454 $d_h = round($s_h / $r);
455
456 $t_w = $d_w;
457 $t_h = $d_h;
458 }
459 break;
460 }
461
462
463
464
465
466 if ($t_h > $d_h)
467 {
468 $d_y = round(($t_h - $d_h) / 2);
469 }
470
471 if ($t_w > $d_w)
472 {
473 $d_x = round(($t_w - $d_w) / 2);
474 }
475
476
477
478
479
480 $destination = imagecreatetruecolor($t_w, $t_h);
481
482
483
484
485
486
487
488 if ($fill_callback)
489 {
490 call_user_func($fill_callback, $destination, $t_w, $t_h);
491 }
492 else
493 {
494 $c = imagecolorallocatealpha($destination, 0, 0, 0, 127);
495
496 imagefill($destination, 0, 0, $c);
497 }
498
499
500
501
502
503 imagecopyresampled
504 (
505 $destination,
506 $source,
507
508 $d_x, $d_y, $s_x, $s_y,
509 $d_w, $d_h, $s_w, $s_h
510 );
511
512 return $destination;
513 }
514
515 516 517 518 519 520 521
522
523 static $grid_sizes = array
524 (
525 'none' => 0,
526 'small' => 4,
527 'medium' => 8,
528 'large' => 16
529 );
530
531 static $grid_color_schemes = array
532 (
533 'light' => array(0xffffff, 0xcccccc),
534 'medium' => array(0x999999, 0x666666),
535 'dark' => array(0x333333, 0x666666),
536 'red' => array(0xffffff, 0xffcccc),
537 'orange' => array(0xffffff, 0xffd8bd),
538 'green' => array(0xffffff, 0xcce4cc),
539 'blue' => array(0xffffff, 0xcce0f8),
540 'purple' => array(0xffffff, 0xdcccf8)
541 );
542
543 static public function draw_grid($image, $x1, $y1, $x2, $y2, $color1=0xFFFFFF, $color2=0xCCCCCC, $size=4)
544 {
545
546
547
548
549 if (is_string($size) && !((int) $size))
550 {
551 $size = isset(self::$grid_sizes[$size]) ? self::$grid_sizes[$size] : 4;
552 }
553
554
555
556
557
558 if (is_string($color1) && isset(self::$grid_color_schemes[$color1]))
559 {
560 list($color1, $color2) = self::$grid_color_schemes[$color1];
561 }
562
563
564
565
566
567 $c1 = self::allocate_color($image, $color1);
568 $c2 = self::allocate_color($image, $color2);
569
570
571
572
573
574 if ($size)
575 {
576
577
578
579
580 for ($j = $y1, $b = 0 ; $j < $y2 ; $j += $size, $b++)
581 {
582 for ($i = $x1, $a = 0 ; $i < $x2 ; $i += $size, $a++)
583 {
584 imagefilledrectangle
585 (
586 $image,
587
588 $i, $j,
589 max($i + $size, $x2),
590 max($j + $size, $y2),
591
592 ($a % 2) ? $c1 : $c2
593 );
594 }
595
596
597
598
599
600
601 $t = $c1;
602 $c1 = $c2;
603 $c2 = $t;
604 }
605 }
606 else
607 {
608
609
610
611
612 imagefilledrectangle($image, $x1, $y1, $x2, $y2, $c1);
613 }
614 }
615
616 617 618 619 620 621
622 static public function decode_color($color)
623 {
624 if (is_array($color))
625 {
626 return $color;
627 }
628
629 if (isset(self::$color_names[$color]))
630 {
631 $color = self::$color_names[$color];
632 }
633
634 if (is_string($color))
635 {
636 if ($color[0] == '#')
637 {
638 switch (strlen($color))
639 {
640 case 4:
641 {
642 return array
643 (
644 intval($color[1] . $color[1], 16),
645 intval($color[2] . $color[2], 16),
646 intval($color[3] . $color[3], 16)
647 );
648 }
649 break;
650
651 case 7:
652 {
653 return array
654 (
655 intval($color[1] . $color[2], 16),
656 intval($color[3] . $color[4], 16),
657 intval($color[5] . $color[6], 16)
658 );
659 }
660 break;
661 }
662 }
663
664
665 }
666 else if (is_numeric($color))
667 {
668 return array
669 (
670 ($color & 0xFF0000) >> 16, ($color & 0x00FF00) >> 8, ($color & 0x0000FF)
671 );
672 }
673
674
675
676
677
678 return array(128, 128, 128);
679 }
680
681 static public function allocate_color($image, $color)
682 {
683 $color = self::decode_color($color);
684
685 return imagecolorallocate
686 (
687 $image, $color[0], $color[1], $color[2]
688 );
689 }
690
691 static public $color_names = array
692 (
693 'snow' => 0xFFFAFA,
694 'snow1' => 0xFFFAFA,
695 'snow2' => 0xEEE9E9,
696 'RosyBrown1' => 0xFFC1C1,
697 'RosyBrown2' => 0xEEB4B4,
698 'snow3' => 0xCDC9C9,
699 'LightCoral' => 0xF08080,
700 'IndianRed1' => 0xFF6A6A,
701 'RosyBrown3' => 0xCD9B9B,
702 'IndianRed2' => 0xEE6363,
703 'RosyBrown' => 0xBC8F8F,
704 'brown1' => 0xFF4040,
705 'firebrick1' => 0xFF3030,
706 'brown2' => 0xEE3B3B,
707 'IndianRed' => 0xCD5C5C,
708 'IndianRed3' => 0xCD5555,
709 'firebrick2' => 0xEE2C2C,
710 'snow4' => 0x8B8989,
711 'brown3' => 0xCD3333,
712 'red' => 0xFF0000,
713 'red1' => 0xFF0000,
714 'RosyBrown4' => 0x8B6969,
715 'firebrick3' => 0xCD2626,
716 'red2' => 0xEE0000,
717 'firebrick' => 0xB22222,
718 'brown' => 0xA52A2A,
719 'red3' => 0xCD0000,
720 'IndianRed4' => 0x8B3A3A,
721 'brown4' => 0x8B2323,
722 'firebrick4' => 0x8B1A1A,
723 'DarkRed' => 0x8B0000,
724 'red4' => 0x8B0000,
725 'maroon' => 0x800000,
726 'LightPink1' => 0xFFAEB9,
727 'LightPink3' => 0xCD8C95,
728 'LightPink4' => 0x8B5F65,
729 'LightPink2' => 0xEEA2AD,
730 'LightPink' => 0xFFB6C1,
731 'pink' => 0xFFC0CB,
732 'crimson' => 0xDC143C,
733 'pink1' => 0xFFB5C5,
734 'pink2' => 0xEEA9B8,
735 'pink3' => 0xCD919E,
736 'pink4' => 0x8B636C,
737 'PaleVioletRed4' => 0x8B475D,
738 'PaleVioletRed' => 0xDB7093,
739 'PaleVioletRed2' => 0xEE799F,
740 'PaleVioletRed1' => 0xFF82AB,
741 'PaleVioletRed3' => 0xCD6889,
742 'LavenderBlush' => 0xFFF0F5,
743 'LavenderBlush1' => 0xFFF0F5,
744 'LavenderBlush3' => 0xCDC1C5,
745 'LavenderBlush2' => 0xEEE0E5,
746 'LavenderBlush4' => 0x8B8386,
747 'maroon' => 0xB03060,
748 'HotPink3' => 0xCD6090,
749 'VioletRed3' => 0xCD3278,
750 'VioletRed1' => 0xFF3E96,
751 'VioletRed2' => 0xEE3A8C,
752 'VioletRed4' => 0x8B2252,
753 'HotPink2' => 0xEE6AA7,
754 'HotPink1' => 0xFF6EB4,
755 'HotPink4' => 0x8B3A62,
756 'HotPink' => 0xFF69B4,
757 'DeepPink' => 0xFF1493,
758 'DeepPink1' => 0xFF1493,
759 'DeepPink2' => 0xEE1289,
760 'DeepPink3' => 0xCD1076,
761 'DeepPink4' => 0x8B0A50,
762 'maroon1' => 0xFF34B3,
763 'maroon2' => 0xEE30A7,
764 'maroon3' => 0xCD2990,
765 'maroon4' => 0x8B1C62,
766 'MediumVioletRed' => 0xC71585,
767 'VioletRed' => 0xD02090,
768 'orchid2' => 0xEE7AE9,
769 'orchid' => 0xDA70D6,
770 'orchid1' => 0xFF83FA,
771 'orchid3' => 0xCD69C9,
772 'orchid4' => 0x8B4789,
773 'thistle1' => 0xFFE1FF,
774 'thistle2' => 0xEED2EE,
775 'plum1' => 0xFFBBFF,
776 'plum2' => 0xEEAEEE,
777 'thistle' => 0xD8BFD8,
778 'thistle3' => 0xCDB5CD,
779 'plum' => 0xDDA0DD,
780 'violet' => 0xEE82EE,
781 'plum3' => 0xCD96CD,
782 'thistle4' => 0x8B7B8B,
783 'fuchsia' => 0xFF00FF,
784 'magenta' => 0xFF00FF,
785 'magenta1' => 0xFF00FF,
786 'plum4' => 0x8B668B,
787 'magenta2' => 0xEE00EE,
788 'magenta3' => 0xCD00CD,
789 'DarkMagenta' => 0x8B008B,
790 'magenta4' => 0x8B008B,
791 'purple' => 0x800080,
792 'MediumOrchid' => 0xBA55D3,
793 'MediumOrchid1' => 0xE066FF,
794 'MediumOrchid2' => 0xD15FEE,
795 'MediumOrchid3' => 0xB452CD,
796 'MediumOrchid4' => 0x7A378B,
797 'DarkViolet' => 0x9400D3,
798 'DarkOrchid' => 0x9932CC,
799 'DarkOrchid1' => 0xBF3EFF,
800 'DarkOrchid3' => 0x9A32CD,
801 'DarkOrchid2' => 0xB23AEE,
802 'DarkOrchid4' => 0x68228B,
803 'purple' => 0xA020F0,
804 'indigo' => 0x4B0082,
805 'BlueViolet' => 0x8A2BE2,
806 'purple2' => 0x912CEE,
807 'purple3' => 0x7D26CD,
808 'purple4' => 0x551A8B,
809 'purple1' => 0x9B30FF,
810 'MediumPurple' => 0x9370DB,
811 'MediumPurple1' => 0xAB82FF,
812 'MediumPurple2' => 0x9F79EE,
813 'MediumPurple3' => 0x8968CD,
814 'MediumPurple4' => 0x5D478B,
815 'DarkSlateBlue' => 0x483D8B,
816 'LightSlateBlue' => 0x8470FF,
817 'MediumSlateBlue' => 0x7B68EE,
818 'SlateBlue' => 0x6A5ACD,
819 'SlateBlue1' => 0x836FFF,
820 'SlateBlue2' => 0x7A67EE,
821 'SlateBlue3' => 0x6959CD,
822 'SlateBlue4' => 0x473C8B,
823 'GhostWhite' => 0xF8F8FF,
824 'lavender' => 0xE6E6FA,
825 'blue' => 0x0000FF,
826 'blue1' => 0x0000FF,
827 'blue2' => 0x0000EE,
828 'blue3' => 0x0000CD,
829 'MediumBlue' => 0x0000CD,
830 'blue4' => 0x00008B,
831 'DarkBlue' => 0x00008B,
832 'MidnightBlue' => 0x191970,
833 'navy' => 0x000080,
834 'NavyBlue' => 0x000080,
835 'RoyalBlue' => 0x4169E1,
836 'RoyalBlue1' => 0x4876FF,
837 'RoyalBlue2' => 0x436EEE,
838 'RoyalBlue3' => 0x3A5FCD,
839 'RoyalBlue4' => 0x27408B,
840 'CornflowerBlue' => 0x6495ED,
841 'LightSteelBlue' => 0xB0C4DE,
842 'LightSteelBlue1' => 0xCAE1FF,
843 'LightSteelBlue2' => 0xBCD2EE,
844 'LightSteelBlue3' => 0xA2B5CD,
845 'LightSteelBlue4' => 0x6E7B8B,
846 'SlateGray4' => 0x6C7B8B,
847 'SlateGray1' => 0xC6E2FF,
848 'SlateGray2' => 0xB9D3EE,
849 'SlateGray3' => 0x9FB6CD,
850 'LightSlateGray' => 0x778899,
851 'LightSlateGrey' => 0x778899,
852 'SlateGray' => 0x708090,
853 'SlateGrey' => 0x708090,
854 'DodgerBlue' => 0x1E90FF,
855 'DodgerBlue1' => 0x1E90FF,
856 'DodgerBlue2' => 0x1C86EE,
857 'DodgerBlue4' => 0x104E8B,
858 'DodgerBlue3' => 0x1874CD,
859 'AliceBlue' => 0xF0F8FF,
860 'SteelBlue4' => 0x36648B,
861 'SteelBlue' => 0x4682B4,
862 'SteelBlue1' => 0x63B8FF,
863 'SteelBlue2' => 0x5CACEE,
864 'SteelBlue3' => 0x4F94CD,
865 'SkyBlue4' => 0x4A708B,
866 'SkyBlue1' => 0x87CEFF,
867 'SkyBlue2' => 0x7EC0EE,
868 'SkyBlue3' => 0x6CA6CD,
869 'LightSkyBlue' => 0x87CEFA,
870 'LightSkyBlue4' => 0x607B8B,
871 'LightSkyBlue1' => 0xB0E2FF,
872 'LightSkyBlue2' => 0xA4D3EE,
873 'LightSkyBlue3' => 0x8DB6CD,
874 'SkyBlue' => 0x87CEEB,
875 'LightBlue3' => 0x9AC0CD,
876 'DeepSkyBlue' => 0x00BFFF,
877 'DeepSkyBlue1' => 0x00BFFF,
878 'DeepSkyBlue2' => 0x00B2EE,
879 'DeepSkyBlue4' => 0x00688B,
880 'DeepSkyBlue3' => 0x009ACD,
881 'LightBlue1' => 0xBFEFFF,
882 'LightBlue2' => 0xB2DFEE,
883 'LightBlue' => 0xADD8E6,
884 'LightBlue4' => 0x68838B,
885 'PowderBlue' => 0xB0E0E6,
886 'CadetBlue1' => 0x98F5FF,
887 'CadetBlue2' => 0x8EE5EE,
888 'CadetBlue3' => 0x7AC5CD,
889 'CadetBlue4' => 0x53868B,
890 'turquoise1' => 0x00F5FF,
891 'turquoise2' => 0x00E5EE,
892 'turquoise3' => 0x00C5CD,
893 'turquoise4' => 0x00868B,
894 'cadet blue' => 0x5F9EA0,
895 'CadetBlue' => 0x5F9EA0,
896 'DarkTurquoise' => 0x00CED1,
897 'azure' => 0xF0FFFF,
898 'azure1' => 0xF0FFFF,
899 'LightCyan' => 0xE0FFFF,
900 'LightCyan1' => 0xE0FFFF,
901 'azure2' => 0xE0EEEE,
902 'LightCyan2' => 0xD1EEEE,
903 'PaleTurquoise1' => 0xBBFFFF,
904 'PaleTurquoise' => 0xAFEEEE,
905 'PaleTurquoise2' => 0xAEEEEE,
906 'DarkSlateGray1' => 0x97FFFF,
907 'azure3' => 0xC1CDCD,
908 'LightCyan3' => 0xB4CDCD,
909 'DarkSlateGray2' => 0x8DEEEE,
910 'PaleTurquoise3' => 0x96CDCD,
911 'DarkSlateGray3' => 0x79CDCD,
912 'azure4' => 0x838B8B,
913 'LightCyan4' => 0x7A8B8B,
914 'aqua' => 0x00FFFF,
915 'cyan' => 0x00FFFF,
916 'cyan1' => 0x00FFFF,
917 'PaleTurquoise4' => 0x668B8B,
918 'cyan2' => 0x00EEEE,
919 'DarkSlateGray4' => 0x528B8B,
920 'cyan3' => 0x00CDCD,
921 'cyan4' => 0x008B8B,
922 'DarkCyan' => 0x008B8B,
923 'teal' => 0x008080,
924 'DarkSlateGray' => 0x2F4F4F,
925 'DarkSlateGrey' => 0x2F4F4F,
926 'MediumTurquoise' => 0x48D1CC,
927 'LightSeaGreen' => 0x20B2AA,
928 'turquoise' => 0x40E0D0,
929 'aquamarine4' => 0x458B74,
930 'aquamarine' => 0x7FFFD4,
931 'aquamarine1' => 0x7FFFD4,
932 'aquamarine2' => 0x76EEC6,
933 'aquamarine3' => 0x66CDAA,
934 'MediumAquamarine' => 0x66CDAA,
935 'MediumSpringGreen' => 0x00FA9A,
936 'MintCream' => 0xF5FFFA,
937 'SpringGreen' => 0x00FF7F,
938 'SpringGreen1' => 0x00FF7F,
939 'SpringGreen2' => 0x00EE76,
940 'SpringGreen3' => 0x00CD66,
941 'SpringGreen4' => 0x008B45,
942 'MediumSeaGreen' => 0x3CB371,
943 'SeaGreen' => 0x2E8B57,
944 'SeaGreen3' => 0x43CD80,
945 'SeaGreen1' => 0x54FF9F,
946 'SeaGreen4' => 0x2E8B57,
947 'SeaGreen2' => 0x4EEE94,
948 'MediumForestGreen' => 0x32814B,
949 'honeydew' => 0xF0FFF0,
950 'honeydew1' => 0xF0FFF0,
951 'honeydew2' => 0xE0EEE0,
952 'DarkSeaGreen1' => 0xC1FFC1,
953 'DarkSeaGreen2' => 0xB4EEB4,
954 'PaleGreen1' => 0x9AFF9A,
955 'PaleGreen' => 0x98FB98,
956 'honeydew3' => 0xC1CDC1,
957 'LightGreen' => 0x90EE90,
958 'PaleGreen2' => 0x90EE90,
959 'DarkSeaGreen3' => 0x9BCD9B,
960 'DarkSeaGreen' => 0x8FBC8F,
961 'PaleGreen3' => 0x7CCD7C,
962 'honeydew4' => 0x838B83,
963 'green1' => 0x00FF00,
964 'lime' => 0x00FF00,
965 'LimeGreen' => 0x32CD32,
966 'DarkSeaGreen4' => 0x698B69,
967 'green2' => 0x00EE00,
968 'PaleGreen4' => 0x548B54,
969 'green3' => 0x00CD00,
970 'ForestGreen' => 0x228B22,
971 'green4' => 0x008B00,
972 'green' => 0x008000,
973 'DarkGreen' => 0x006400,
974 'LawnGreen' => 0x7CFC00,
975 'chartreuse' => 0x7FFF00,
976 'chartreuse1' => 0x7FFF00,
977 'chartreuse2' => 0x76EE00,
978 'chartreuse3' => 0x66CD00,
979 'chartreuse4' => 0x458B00,
980 'GreenYellow' => 0xADFF2F,
981 'DarkOliveGreen3' => 0xA2CD5A,
982 'DarkOliveGreen1' => 0xCAFF70,
983 'DarkOliveGreen2' => 0xBCEE68,
984 'DarkOliveGreen4' => 0x6E8B3D,
985 'DarkOliveGreen' => 0x556B2F,
986 'OliveDrab' => 0x6B8E23,
987 'OliveDrab1' => 0xC0FF3E,
988 'OliveDrab2' => 0xB3EE3A,
989 'OliveDrab3' => 0x9ACD32,
990 'YellowGreen' => 0x9ACD32,
991 'OliveDrab4' => 0x698B22,
992 'ivory' => 0xFFFFF0,
993 'ivory1' => 0xFFFFF0,
994 'LightYellow' => 0xFFFFE0,
995 'LightYellow1' => 0xFFFFE0,
996 'beige' => 0xF5F5DC,
997 'ivory2' => 0xEEEEE0,
998 'LightGoldenrodYellow' => 0xFAFAD2,
999 'LightYellow2' => 0xEEEED1,
1000 'ivory3' => 0xCDCDC1,
1001 'LightYellow3' => 0xCDCDB4,
1002 'ivory4' => 0x8B8B83,
1003 'LightYellow4' => 0x8B8B7A,
1004 'yellow' => 0xFFFF00,
1005 'yellow1' => 0xFFFF00,
1006 'yellow2' => 0xEEEE00,
1007 'yellow3' => 0xCDCD00,
1008 'yellow4' => 0x8B8B00,
1009 'olive' => 0x808000,
1010 'DarkKhaki' => 0xBDB76B,
1011 'khaki2' => 0xEEE685,
1012 'LemonChiffon4' => 0x8B8970,
1013 'khaki1' => 0xFFF68F,
1014 'khaki3' => 0xCDC673,
1015 'khaki4' => 0x8B864E,
1016 'PaleGoldenrod' => 0xEEE8AA,
1017 'LemonChiffon' => 0xFFFACD,
1018 'LemonChiffon1' => 0xFFFACD,
1019 'khaki' => 0xF0E68C,
1020 'LemonChiffon3' => 0xCDC9A5,
1021 'LemonChiffon2' => 0xEEE9BF,
1022 'MediumGoldenRod' => 0xD1C166,
1023 'cornsilk4' => 0x8B8878,
1024 'gold' => 0xFFD700,
1025 'gold1' => 0xFFD700,
1026 'gold2' => 0xEEC900,
1027 'gold3' => 0xCDAD00,
1028 'gold4' => 0x8B7500,
1029 'LightGoldenrod' => 0xEEDD82,
1030 'LightGoldenrod4' => 0x8B814C,
1031 'LightGoldenrod1' => 0xFFEC8B,
1032 'LightGoldenrod3' => 0xCDBE70,
1033 'LightGoldenrod2' => 0xEEDC82,
1034 'cornsilk3' => 0xCDC8B1,
1035 'cornsilk2' => 0xEEE8CD,
1036 'cornsilk' => 0xFFF8DC,
1037 'cornsilk1' => 0xFFF8DC,
1038 'goldenrod' => 0xDAA520,
1039 'goldenrod1' => 0xFFC125,
1040 'goldenrod2' => 0xEEB422,
1041 'goldenrod3' => 0xCD9B1D,
1042 'goldenrod4' => 0x8B6914,
1043 'DarkGoldenrod' => 0xB8860B,
1044 'DarkGoldenrod1' => 0xFFB90F,
1045 'DarkGoldenrod2' => 0xEEAD0E,
1046 'DarkGoldenrod3' => 0xCD950C,
1047 'DarkGoldenrod4' => 0x8B6508,
1048 'FloralWhite' => 0xFFFAF0,
1049 'wheat2' => 0xEED8AE,
1050 'OldLace' => 0xFDF5E6,
1051 'wheat' => 0xF5DEB3,
1052 'wheat1' => 0xFFE7BA,
1053 'wheat3' => 0xCDBA96,
1054 'orange' => 0xFFA500,
1055 'orange1' => 0xFFA500,
1056 'orange2' => 0xEE9A00,
1057 'orange3' => 0xCD8500,
1058 'orange4' => 0x8B5A00,
1059 'wheat4' => 0x8B7E66,
1060 'moccasin' => 0xFFE4B5,
1061 'PapayaWhip' => 0xFFEFD5,
1062 'NavajoWhite3' => 0xCDB38B,
1063 'BlanchedAlmond' => 0xFFEBCD,
1064 'NavajoWhite' => 0xFFDEAD,
1065 'NavajoWhite1' => 0xFFDEAD,
1066 'NavajoWhite2' => 0xEECFA1,
1067 'NavajoWhite4' => 0x8B795E,
1068 'AntiqueWhite4' => 0x8B8378,
1069 'AntiqueWhite' => 0xFAEBD7,
1070 'tan' => 0xD2B48C,
1071 'bisque4' => 0x8B7D6B,
1072 'burlywood' => 0xDEB887,
1073 'AntiqueWhite2' => 0xEEDFCC,
1074 'burlywood1' => 0xFFD39B,
1075 'burlywood3' => 0xCDAA7D,
1076 'burlywood2' => 0xEEC591,
1077 'AntiqueWhite1' => 0xFFEFDB,
1078 'burlywood4' => 0x8B7355,
1079 'AntiqueWhite3' => 0xCDC0B0,
1080 'DarkOrange' => 0xFF8C00,
1081 'bisque2' => 0xEED5B7,
1082 'bisque' => 0xFFE4C4,
1083 'bisque1' => 0xFFE4C4,
1084 'bisque3' => 0xCDB79E,
1085 'DarkOrange1' => 0xFF7F00,
1086 'linen' => 0xFAF0E6,
1087 'DarkOrange2' => 0xEE7600,
1088 'DarkOrange3' => 0xCD6600,
1089 'DarkOrange4' => 0x8B4500,
1090 'peru' => 0xCD853F,
1091 'tan1' => 0xFFA54F,
1092 'tan2' => 0xEE9A49,
1093 'tan3' => 0xCD853F,
1094 'tan4' => 0x8B5A2B,
1095 'PeachPuff' => 0xFFDAB9,
1096 'PeachPuff1' => 0xFFDAB9,
1097 'PeachPuff4' => 0x8B7765,
1098 'PeachPuff2' => 0xEECBAD,
1099 'PeachPuff3' => 0xCDAF95,
1100 'SandyBrown' => 0xF4A460,
1101 'seashell4' => 0x8B8682,
1102 'seashell2' => 0xEEE5DE,
1103 'seashell3' => 0xCDC5BF,
1104 'chocolate' => 0xD2691E,
1105 'chocolate1' => 0xFF7F24,
1106 'chocolate2' => 0xEE7621,
1107 'chocolate3' => 0xCD661D,
1108 'chocolate4' => 0x8B4513,
1109 'SaddleBrown' => 0x8B4513,
1110 'seashell' => 0xFFF5EE,
1111 'seashell1' => 0xFFF5EE,
1112 'sienna4' => 0x8B4726,
1113 'sienna' => 0xA0522D,
1114 'sienna1' => 0xFF8247,
1115 'sienna2' => 0xEE7942,
1116 'sienna3' => 0xCD6839,
1117 'LightSalmon3' => 0xCD8162,
1118 'LightSalmon' => 0xFFA07A,
1119 'LightSalmon1' => 0xFFA07A,
1120 'LightSalmon4' => 0x8B5742,
1121 'LightSalmon2' => 0xEE9572,
1122 'coral' => 0xFF7F50,
1123 'OrangeRed' => 0xFF4500,
1124 'OrangeRed1' => 0xFF4500,
1125 'OrangeRed2' => 0xEE4000,
1126 'OrangeRed3' => 0xCD3700,
1127 'OrangeRed4' => 0x8B2500,
1128 'DarkSalmon' => 0xE9967A,
1129 'salmon1' => 0xFF8C69,
1130 'salmon2' => 0xEE8262,
1131 'salmon3' => 0xCD7054,
1132 'salmon4' => 0x8B4C39,
1133 'coral1' => 0xFF7256,
1134 'coral2' => 0xEE6A50,
1135 'coral3' => 0xCD5B45,
1136 'coral4' => 0x8B3E2F,
1137 'tomato4' => 0x8B3626,
1138 'tomato' => 0xFF6347,
1139 'tomato1' => 0xFF6347,
1140 'tomato2' => 0xEE5C42,
1141 'tomato3' => 0xCD4F39,
1142 'MistyRose4' => 0x8B7D7B,
1143 'MistyRose2' => 0xEED5D2,
1144 'MistyRose' => 0xFFE4E1,
1145 'MistyRose1' => 0xFFE4E1,
1146 'salmon' => 0xFA8072,
1147 'MistyRose3' => 0xCDB7B5,
1148 'white' => 0xFFFFFF,
1149 'gray100' => 0xFFFFFF,
1150 'grey100' => 0xFFFFFF,
1151 'grey100' => 0xFFFFFF,
1152 'gray99' => 0xFCFCFC,
1153 'grey99' => 0xFCFCFC,
1154 'gray98' => 0xFAFAFA,
1155 'grey98' => 0xFAFAFA,
1156 'gray97' => 0xF7F7F7,
1157 'grey97' => 0xF7F7F7,
1158 'gray96' => 0xF5F5F5,
1159 'grey96' => 0xF5F5F5,
1160 'WhiteSmoke' => 0xF5F5F5,
1161 'gray95' => 0xF2F2F2,
1162 'grey95' => 0xF2F2F2,
1163 'gray94' => 0xF0F0F0,
1164 'grey94' => 0xF0F0F0,
1165 'gray93' => 0xEDEDED,
1166 'grey93' => 0xEDEDED,
1167 'gray92' => 0xEBEBEB,
1168 'grey92' => 0xEBEBEB,
1169 'gray91' => 0xE8E8E8,
1170 'grey91' => 0xE8E8E8,
1171 'gray90' => 0xE5E5E5,
1172 'grey90' => 0xE5E5E5,
1173 'gray89' => 0xE3E3E3,
1174 'grey89' => 0xE3E3E3,
1175 'gray88' => 0xE0E0E0,
1176 'grey88' => 0xE0E0E0,
1177 'gray87' => 0xDEDEDE,
1178 'grey87' => 0xDEDEDE,
1179 'gainsboro' => 0xDCDCDC,
1180 'gray86' => 0xDBDBDB,
1181 'grey86' => 0xDBDBDB,
1182 'gray85' => 0xD9D9D9,
1183 'grey85' => 0xD9D9D9,
1184 'gray84' => 0xD6D6D6,
1185 'grey84' => 0xD6D6D6,
1186 'gray83' => 0xD4D4D4,
1187 'grey83' => 0xD4D4D4,
1188 'LightGray' => 0xD3D3D3,
1189 'LightGrey' => 0xD3D3D3,
1190 'gray82' => 0xD1D1D1,
1191 'grey82' => 0xD1D1D1,
1192 'gray81' => 0xCFCFCF,
1193 'grey81' => 0xCFCFCF,
1194 'gray80' => 0xCCCCCC,
1195 'grey80' => 0xCCCCCC,
1196 'gray79' => 0xC9C9C9,
1197 'grey79' => 0xC9C9C9,
1198 'gray78' => 0xC7C7C7,
1199 'grey78' => 0xC7C7C7,
1200 'gray77' => 0xC4C4C4,
1201 'grey77' => 0xC4C4C4,
1202 'gray76' => 0xC2C2C2,
1203 'grey76' => 0xC2C2C2,
1204 'silver' => 0xC0C0C0,
1205 'gray75' => 0xBFBFBF,
1206 'grey75' => 0xBFBFBF,
1207 'gray' => 0xBEBEBE,
1208 'grey' => 0xBEBEBE,
1209 'gray74' => 0xBDBDBD,
1210 'grey74' => 0xBDBDBD,
1211 'gray73' => 0xBABABA,
1212 'grey73' => 0xBABABA,
1213 'gray72' => 0xB8B8B8,
1214 'grey72' => 0xB8B8B8,
1215 'gray71' => 0xB5B5B5,
1216 'grey71' => 0xB5B5B5,
1217 'gray70' => 0xB3B3B3,
1218 'grey70' => 0xB3B3B3,
1219 'gray69' => 0xB0B0B0,
1220 'grey69' => 0xB0B0B0,
1221 'gray68' => 0xADADAD,
1222 'grey68' => 0xADADAD,
1223 'gray67' => 0xABABAB,
1224 'grey67' => 0xABABAB,
1225 'DarkGray' => 0xA9A9A9,
1226 'DarkGrey' => 0xA9A9A9,
1227 'gray66' => 0xA8A8A8,
1228 'grey66' => 0xA8A8A8,
1229 'gray65' => 0xA6A6A6,
1230 'grey65' => 0xA6A6A6,
1231 'gray64' => 0xA3A3A3,
1232 'grey64' => 0xA3A3A3,
1233 'gray63' => 0xA1A1A1,
1234 'grey63' => 0xA1A1A1,
1235 'gray62' => 0x9E9E9E,
1236 'grey62' => 0x9E9E9E,
1237 'gray61' => 0x9C9C9C,
1238 'grey61' => 0x9C9C9C,
1239 'gray60' => 0x999999,
1240 'grey60' => 0x999999,
1241 'gray59' => 0x969696,
1242 'grey59' => 0x969696,
1243 'gray58' => 0x949494,
1244 'grey58' => 0x949494,
1245 'gray57' => 0x919191,
1246 'grey57' => 0x919191,
1247 'gray56' => 0x8F8F8F,
1248 'grey56' => 0x8F8F8F,
1249 'gray55' => 0x8C8C8C,
1250 'grey55' => 0x8C8C8C,
1251 'gray54' => 0x8A8A8A,
1252 'grey54' => 0x8A8A8A,
1253 'gray53' => 0x878787,
1254 'grey53' => 0x878787,
1255 'gray52' => 0x858585,
1256 'grey52' => 0x858585,
1257 'gray51' => 0x828282,
1258 'grey51' => 0x828282,
1259 'fractal' => 0x808080,
1260 'gray50' => 0x7F7F7F,
1261 'grey50' => 0x7F7F7F,
1262 'gray' => 0x7E7E7E,
1263 'gray49' => 0x7D7D7D,
1264 'grey49' => 0x7D7D7D,
1265 'gray48' => 0x7A7A7A,
1266 'grey48' => 0x7A7A7A,
1267 'gray47' => 0x787878,
1268 'grey47' => 0x787878,
1269 'gray46' => 0x757575,
1270 'grey46' => 0x757575,
1271 'gray45' => 0x737373,
1272 'grey45' => 0x737373,
1273 'gray44' => 0x707070,
1274 'grey44' => 0x707070,
1275 'gray43' => 0x6E6E6E,
1276 'grey43' => 0x6E6E6E,
1277 'gray42' => 0x6B6B6B,
1278 'grey42' => 0x6B6B6B,
1279 'DimGray' => 0x696969,
1280 'DimGrey' => 0x696969,
1281 'gray41' => 0x696969,
1282 'grey41' => 0x696969,
1283 'gray40' => 0x666666,
1284 'grey40' => 0x666666,
1285 'gray39' => 0x636363,
1286 'grey39' => 0x636363,
1287 'gray38' => 0x616161,
1288 'grey38' => 0x616161,
1289 'gray37' => 0x5E5E5E,
1290 'grey37' => 0x5E5E5E,
1291 'gray36' => 0x5C5C5C,
1292 'grey36' => 0x5C5C5C,
1293 'gray35' => 0x595959,
1294 'grey35' => 0x595959,
1295 'gray34' => 0x575757,
1296 'grey34' => 0x575757,
1297 'gray33' => 0x545454,
1298 'grey33' => 0x545454,
1299 'gray32' => 0x525252,
1300 'grey32' => 0x525252,
1301 'gray31' => 0x4F4F4F,
1302 'grey31' => 0x4F4F4F,
1303 'gray30' => 0x4D4D4D,
1304 'grey30' => 0x4D4D4D,
1305 'gray29' => 0x4A4A4A,
1306 'grey29' => 0x4A4A4A,
1307 'gray28' => 0x474747,
1308 'grey28' => 0x474747,
1309 'gray27' => 0x454545,
1310 'grey27' => 0x454545,
1311 'gray26' => 0x424242,
1312 'grey26' => 0x424242,
1313 'gray25' => 0x404040,
1314 'grey25' => 0x404040,
1315 'gray24' => 0x3D3D3D,
1316 'grey24' => 0x3D3D3D,
1317 'gray23' => 0x3B3B3B,
1318 'grey23' => 0x3B3B3B,
1319 'gray22' => 0x383838,
1320 'grey22' => 0x383838,
1321 'gray21' => 0x363636,
1322 'grey21' => 0x363636,
1323 'gray20' => 0x333333,
1324 'grey20' => 0x333333,
1325 'gray19' => 0x303030,
1326 'grey19' => 0x303030,
1327 'gray18' => 0x2E2E2E,
1328 'grey18' => 0x2E2E2E,
1329 'gray17' => 0x2B2B2B,
1330 'grey17' => 0x2B2B2B,
1331 'gray16' => 0x292929,
1332 'grey16' => 0x292929,
1333 'gray15' => 0x262626,
1334 'grey15' => 0x262626,
1335 'gray14' => 0x242424,
1336 'grey14' => 0x242424,
1337 'gray13' => 0x212121,
1338 'grey13' => 0x212121,
1339 'gray12' => 0x1F1F1F,
1340 'grey12' => 0x1F1F1F,
1341 'gray11' => 0x1C1C1C,
1342 'grey11' => 0x1C1C1C,
1343 'gray10' => 0x1A1A1A,
1344 'grey10' => 0x1A1A1A,
1345 'gray9' => 0x171717,
1346 'grey9' => 0x171717,
1347 'gray8' => 0x141414,
1348 'grey8' => 0x141414,
1349 'gray7' => 0x121212,
1350 'grey7' => 0x121212,
1351 'gray6' => 0x0F0F0F,
1352 'grey6' => 0x0F0F0F,
1353 'gray5' => 0x0D0D0D,
1354 'grey5' => 0x0D0D0D,
1355 'gray4' => 0x0A0A0A,
1356 'grey4' => 0x0A0A0A,
1357 'gray3' => 0x080808,
1358 'grey3' => 0x080808,
1359 'gray2' => 0x050505,
1360 'grey2' => 0x050505,
1361 'gray1' => 0x030303,
1362 'grey1' => 0x030303,
1363 'black' => 0x000000,
1364 'gray0' => 0x000000,
1365 'grey0' => 0x000000
1366 );
1367 }