Mercurial > hg > rc1
comparison plugins/identicon/identicon_engine.php @ 0:1e000243b222
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:50:29 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e000243b222 |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @license GNU GPLv3+ | |
5 * @author Aleksander Machniak <alec@alec.pl> | |
6 */ | |
7 class identicon_engine | |
8 { | |
9 private $ident; | |
10 private $width; | |
11 private $height; | |
12 private $margin; | |
13 private $binary; | |
14 private $color; | |
15 private $bgcolor = '#F9F9F9'; | |
16 private $mimetype = 'image/png'; | |
17 private $palette = array( | |
18 '#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3', | |
19 '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', | |
20 '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#795548', '#607D8B', | |
21 ); | |
22 private $grid = array( | |
23 0, 1, 2, 1, 0, | |
24 3, 4, 5, 4, 3, | |
25 6, 7, 8, 7, 6, | |
26 9, 10, 11, 10, 9, | |
27 12, 13, 14, 13, 12, | |
28 ); | |
29 | |
30 const GRID_SIZE = 5; | |
31 const ICON_SIZE = 150; | |
32 | |
33 | |
34 /** | |
35 * Class constructor | |
36 * | |
37 * @param string $ident Unique identifier (email address) | |
38 * @param int $size Icon size in pixels | |
39 */ | |
40 public function __construct($ident, $size = null) | |
41 { | |
42 if (!$size) { | |
43 $size = self::ICON_SIZE; | |
44 } | |
45 | |
46 $this->ident = $ident; | |
47 $this->margin = (int) round($size / 10); | |
48 $this->width = (int) round(($size - $this->margin * 2) / self::GRID_SIZE) * self::GRID_SIZE + $this->margin * 2; | |
49 $this->height = $this->width; | |
50 | |
51 $this->generate(); | |
52 } | |
53 | |
54 /** | |
55 * Returns image mimetype | |
56 */ | |
57 public function getMimetype() | |
58 { | |
59 return $this->mimetype; | |
60 } | |
61 | |
62 /** | |
63 * Returns the image in binary form | |
64 */ | |
65 public function getBinary() | |
66 { | |
67 return $this->binary; | |
68 } | |
69 | |
70 /** | |
71 * Sends the image to the browser | |
72 */ | |
73 public function sendOutput() | |
74 { | |
75 if ($this->binary) { | |
76 $rcmail = rcmail::get_instance(); | |
77 $rcmail->output->future_expire_header(10 * 60); | |
78 | |
79 header('Content-Type: ' . $this->mimetype); | |
80 header('Content-Size: ' . strlen($this->binary)); | |
81 echo $this->binary; | |
82 | |
83 return true; | |
84 } | |
85 | |
86 return false; | |
87 } | |
88 | |
89 /** | |
90 * Icon generator | |
91 */ | |
92 private function generate() | |
93 { | |
94 $ident = md5($this->ident, true); | |
95 | |
96 // set icon color | |
97 $div = intval(255/count($this->palette)); | |
98 $index = intval(ord($ident[0]) / $div); | |
99 $this->color = $this->palette[$index] ?: $this->palette[0]; | |
100 | |
101 // set cell size | |
102 $cell_width = ($this->width - $this->margin * 2) / self::GRID_SIZE; | |
103 $cell_height = ($this->height - $this->margin * 2) / self::GRID_SIZE; | |
104 | |
105 // create a grid | |
106 foreach ($this->grid as $i => $idx) { | |
107 $row_num = intval($i / self::GRID_SIZE); | |
108 $cell_num_h = $i - $row_num * self::GRID_SIZE; | |
109 | |
110 $this->grid[$i] = array( | |
111 'active' => ord($ident[$idx]) % 2 > 0, | |
112 'x1' => $cell_width * $cell_num_h + $this->margin, | |
113 'y1' => $cell_height * $row_num + $this->margin, | |
114 'x2' => $cell_width * ($cell_num_h + 1) + $this->margin, | |
115 'y2' => $cell_height * ($row_num + 1) + $this->margin, | |
116 ); | |
117 } | |
118 | |
119 // really generate the image using supported methods | |
120 if (function_exists('imagepng')) { | |
121 $this->generateGD(); | |
122 } | |
123 else { | |
124 // log an error | |
125 $error = array( | |
126 'code' => 500, | |
127 'message' => "PHP-GD module not found. It's required by identicon plugin.", | |
128 ); | |
129 | |
130 rcube::raise_error($error, true, false); | |
131 } | |
132 } | |
133 | |
134 /** | |
135 * GD-based icon generation worker | |
136 */ | |
137 private function generateGD() | |
138 { | |
139 $color = $this->toRGB($this->color); | |
140 $bgcolor = $this->toRGB($this->bgcolor); | |
141 | |
142 // create an image, setup colors | |
143 $image = imagecreate($this->width, $this->height); | |
144 $color = imagecolorallocate($image, $color[0], $color[1], $color[2]); | |
145 $bgcolor = imagecolorallocate($image, $bgcolor[0], $bgcolor[1], $bgcolor[2]); | |
146 | |
147 imagefilledrectangle($image, 0, 0, $this->width, $this->height, $bgcolor); | |
148 | |
149 // draw the grid created in self::generate() | |
150 foreach ($this->grid as $item) { | |
151 if ($item['active']) { | |
152 imagefilledrectangle($image, $item['x1'], $item['y1'], $item['x2'], $item['y2'], $color); | |
153 } | |
154 } | |
155 | |
156 // generate an image and save it to a variable | |
157 ob_start(); | |
158 imagepng($image, null, 6, PNG_ALL_FILTERS); | |
159 $this->binary = ob_get_contents(); | |
160 ob_end_clean(); | |
161 | |
162 // cleanup | |
163 imagedestroy($image); | |
164 } | |
165 | |
166 /** | |
167 * Convert #FFFFFF color format to 3-value RGB | |
168 */ | |
169 private function toRGB($color) | |
170 { | |
171 preg_match('/^#?([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/i', $color, $m); | |
172 | |
173 return array(hexdec($m[1]), hexdec($m[2]), hexdec($m[3])); | |
174 } | |
175 } |