123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <?php
-
- /**
- * @license GNU GPLv3+
- * @author Aleksander Machniak <alec@alec.pl>
- */
- class identicon_engine
- {
- private $ident;
- private $width;
- private $height;
- private $margin;
- private $binary;
- private $color;
- private $bgcolor = '#F9F9F9';
- private $mimetype = 'image/png';
- private $palette = array(
- '#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3',
- '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39',
- '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#795548', '#607D8B',
- );
- private $grid = array(
- 0, 1, 2, 1, 0,
- 3, 4, 5, 4, 3,
- 6, 7, 8, 7, 6,
- 9, 10, 11, 10, 9,
- 12, 13, 14, 13, 12,
- );
-
- const GRID_SIZE = 5;
- const ICON_SIZE = 150;
-
-
- /**
- * Class constructor
- *
- * @param string $ident Unique identifier (email address)
- * @param int $size Icon size in pixels
- */
- public function __construct($ident, $size = null)
- {
- if (!$size) {
- $size = self::ICON_SIZE;
- }
-
- $this->ident = $ident;
- $this->margin = (int) round($size / 10);
- $this->width = (int) round(($size - $this->margin * 2) / self::GRID_SIZE) * self::GRID_SIZE + $this->margin * 2;
- $this->height = $this->width;
-
- $this->generate();
- }
-
- /**
- * Returns image mimetype
- */
- public function getMimetype()
- {
- return $this->mimetype;
- }
-
- /**
- * Returns the image in binary form
- */
- public function getBinary()
- {
- return $this->binary;
- }
-
- /**
- * Sends the image to the browser
- */
- public function sendOutput()
- {
- if ($this->binary) {
- $rcmail = rcmail::get_instance();
- $rcmail->output->future_expire_header(10 * 60);
-
- header('Content-Type: ' . $this->mimetype);
- header('Content-Size: ' . strlen($this->binary));
- echo $this->binary;
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Icon generator
- */
- private function generate()
- {
- $ident = md5($this->ident, true);
-
- // set icon color
- $div = intval(255/count($this->palette));
- $index = intval(ord($ident[0]) / $div);
- $this->color = $this->palette[$index] ?: $this->palette[0];
-
- // set cell size
- $cell_width = ($this->width - $this->margin * 2) / self::GRID_SIZE;
- $cell_height = ($this->height - $this->margin * 2) / self::GRID_SIZE;
-
- // create a grid
- foreach ($this->grid as $i => $idx) {
- $row_num = intval($i / self::GRID_SIZE);
- $cell_num_h = $i - $row_num * self::GRID_SIZE;
-
- $this->grid[$i] = array(
- 'active' => ord($ident[$idx]) % 2 > 0,
- 'x1' => $cell_width * $cell_num_h + $this->margin,
- 'y1' => $cell_height * $row_num + $this->margin,
- 'x2' => $cell_width * ($cell_num_h + 1) + $this->margin,
- 'y2' => $cell_height * ($row_num + 1) + $this->margin,
- );
- }
-
- // really generate the image using supported methods
- if (function_exists('imagepng')) {
- $this->generateGD();
- }
- else {
- // log an error
- $error = array(
- 'code' => 500,
- 'message' => "PHP-GD module not found. It's required by identicon plugin.",
- );
-
- rcube::raise_error($error, true, false);
- }
- }
-
- /**
- * GD-based icon generation worker
- */
- private function generateGD()
- {
- $color = $this->toRGB($this->color);
- $bgcolor = $this->toRGB($this->bgcolor);
-
- // create an image, setup colors
- $image = imagecreate($this->width, $this->height);
- $color = imagecolorallocate($image, $color[0], $color[1], $color[2]);
- $bgcolor = imagecolorallocate($image, $bgcolor[0], $bgcolor[1], $bgcolor[2]);
-
- imagefilledrectangle($image, 0, 0, $this->width, $this->height, $bgcolor);
-
- // draw the grid created in self::generate()
- foreach ($this->grid as $item) {
- if ($item['active']) {
- imagefilledrectangle($image, $item['x1'], $item['y1'], $item['x2'], $item['y2'], $color);
- }
- }
-
- // generate an image and save it to a variable
- ob_start();
- imagepng($image, null, 6, PNG_ALL_FILTERS);
- $this->binary = ob_get_contents();
- ob_end_clean();
-
- // cleanup
- imagedestroy($image);
- }
-
- /**
- * Convert #FFFFFF color format to 3-value RGB
- */
- private function toRGB($color)
- {
- preg_match('/^#?([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/i', $color, $m);
-
- return array(hexdec($m[1]), hexdec($m[2]), hexdec($m[3]));
- }
- }
|