1<?php 2/** 3 * MonsterID Generator for DokuWiki Avatar Plugin 4 * 5 * Generates identicon-style monster avatars based on a seed. 6 * Requires PHP GD extension. 7 * 8 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 9 * @author Andreas Gohr <andi@splitbrain.org> 10 * @author Daniel Dias Rodrigues <danieldiasr@gmail.com> (modernization) 11 */ 12 13declare(strict_types=1); 14 15if (php_sapi_name() !== 'cli') { 16 $seed = preg_replace('/[^a-f0-9]/i', '', $_GET['seed'] ?? ''); 17 $size = (int) ($_GET['size'] ?? 120); 18 $size = max(20, min(512, $size)); // limits between 20 and 512 pixels 19 20 header('Content-Type: image/png'); 21 header('Cache-Control: public, max-age=86400'); 22 23 $image = generate_monster($seed, $size); 24 if ($image) { 25 imagepng($image); 26 imagedestroy($image); 27 } else { 28 http_response_code(500); 29 echo 'Erro ao gerar imagem.'; 30 } 31 exit; 32} 33 34/** 35 * Generates monster image based on seed and size 36 */ 37function generate_monster(string $seed, int $size): ?GdImage 38{ 39 if (!function_exists('imagecreatetruecolor')) { 40 return null; 41 } 42 43 $hash = md5($seed); 44 45 $parts = [ 46 'legs' => get_part(substr($hash, 0, 2), 1, 5), 47 'hair' => get_part(substr($hash, 2, 2), 1, 5), 48 'arms' => get_part(substr($hash, 4, 2), 1, 5), 49 'body' => get_part(substr($hash, 6, 2), 1, 15), 50 'eyes' => get_part(substr($hash, 8, 2), 1, 15), 51 'mouth' => get_part(substr($hash, 10, 2), 1, 10), 52 ]; 53 54 $monster = imagecreatetruecolor(120, 120); 55 if (!$monster) return null; 56 57 $white = @imagecolorallocate($monster, 255, 255, 255); 58 imagefill($monster, 0, 0, $white); 59 60 foreach ($parts as $part => $index) { 61 $filename = __DIR__ . '/parts/' . $part . '_' . $index . '.png'; 62 if (!file_exists($filename)) continue; 63 $part_img = imagecreatefrompng($filename); 64 imageSaveAlpha($part_img, true); 65 if ($part_img) { 66 imagecopy($monster, $part_img, 0, 0, 0, 0, 120, 120); 67 imagedestroy($part_img); 68 } 69 } 70 71 if ($size !== 120) { 72 $resized = imagecreatetruecolor($size, $size); 73 imagefill($resized, 0, 0, $white); 74 imagecopyresampled($resized, $monster, 0, 0, 0, 0, $size, $size, 120, 120); 75 imagedestroy($monster); 76 return $resized; 77 } 78 79 return $monster; 80} 81 82/** 83 * Converts part of the hash into an image index 84 */ 85function get_part(string $hex, int $min, int $max): int 86{ 87 $val = hexdec($hex); 88 return ($val % ($max - $min + 1)) + $min; 89} 90 91