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 } |
