xref: /plugin/avatar/monsterid.php (revision 4bc5a5490fec7c45b4b4c984a875c52cb8ca06bd) !
1401a61e7Swikidesign<?php
21affe9b7Swikidesign/**
36e2b7c94Snerun * MonsterID Generator for DokuWiki Avatar Plugin
46e2b7c94Snerun *
56e2b7c94Snerun * Generates identicon-style monster avatars based on a seed.
66e2b7c94Snerun * Requires PHP GD extension.
76e2b7c94Snerun *
81affe9b7Swikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
91affe9b7Swikidesign * @author  Andreas Gohr <andi@splitbrain.org>
106e2b7c94Snerun * @author  Daniel Dias Rodrigues <danieldiasr@gmail.com> (modernization)
111affe9b7Swikidesign */
12401a61e7Swikidesign
136e2b7c94Snerundeclare(strict_types=1);
146e2b7c94Snerun
156e2b7c94Snerunif (php_sapi_name() !== 'cli') {
166e2b7c94Snerun    $seed = preg_replace('/[^a-f0-9]/i', '', $_GET['seed'] ?? '');
176e2b7c94Snerun    $size = (int) ($_GET['size'] ?? 120);
186e2b7c94Snerun    $size = max(20, min(512, $size)); // limits between 20 and 512 pixels
196e2b7c94Snerun
206e2b7c94Snerun    header('Content-Type: image/png');
216e2b7c94Snerun    header('Cache-Control: public, max-age=86400');
226e2b7c94Snerun
236e2b7c94Snerun    $image = generate_monster($seed, $size);
246e2b7c94Snerun    if ($image) {
256e2b7c94Snerun        imagepng($image);
266e2b7c94Snerun        imagedestroy($image);
276e2b7c94Snerun    } else {
286e2b7c94Snerun        http_response_code(500);
296e2b7c94Snerun        echo 'Erro ao gerar imagem.';
306e2b7c94Snerun    }
316e2b7c94Snerun    exit;
326e2b7c94Snerun}
33401a61e7Swikidesign
341affe9b7Swikidesign/**
356e2b7c94Snerun * Generates monster image based on seed and size
361affe9b7Swikidesign */
376e2b7c94Snerunfunction generate_monster(string $seed, int $size): ?GdImage
386e2b7c94Snerun{
396e2b7c94Snerun    if (!function_exists('imagecreatetruecolor')) {
406e2b7c94Snerun        return null;
416e2b7c94Snerun    }
426e2b7c94Snerun
432e0c1c6eSGina Haeussge    $hash = md5($seed);
44401a61e7Swikidesign
456e2b7c94Snerun    $parts = [
466e2b7c94Snerun        'legs'  => get_part(substr($hash, 0, 2), 1, 5),
476e2b7c94Snerun        'hair'  => get_part(substr($hash, 2, 2), 1, 5),
486e2b7c94Snerun        'arms'  => get_part(substr($hash, 4, 2), 1, 5),
496e2b7c94Snerun        'body'  => get_part(substr($hash, 6, 2), 1, 15),
506e2b7c94Snerun        'eyes'  => get_part(substr($hash, 8, 2), 1, 15),
516e2b7c94Snerun        'mouth' => get_part(substr($hash, 10, 2), 1, 10),
526e2b7c94Snerun    ];
53401a61e7Swikidesign
546e2b7c94Snerun    $monster = imagecreatetruecolor(120, 120);
556e2b7c94Snerun    if (!$monster) return null;
566e2b7c94Snerun
57*4bc5a549Snerun    $white = @imagecolorallocate($monster, 255, 255, 255);
58401a61e7Swikidesign    imagefill($monster, 0, 0, $white);
59401a61e7Swikidesign
606e2b7c94Snerun    foreach ($parts as $part => $index) {
61*4bc5a549Snerun        $filename = __DIR__ . '/parts/' . $part . '_' . $index . '.png';
626e2b7c94Snerun        if (!file_exists($filename)) continue;
636e2b7c94Snerun        $part_img = imagecreatefrompng($filename);
64*4bc5a549Snerun        imageSaveAlpha($part_img, true);
656e2b7c94Snerun        if ($part_img) {
666e2b7c94Snerun            imagecopy($monster, $part_img, 0, 0, 0, 0, 120, 120);
676e2b7c94Snerun            imagedestroy($part_img);
68401a61e7Swikidesign        }
69401a61e7Swikidesign    }
70401a61e7Swikidesign
716e2b7c94Snerun    if ($size !== 120) {
726e2b7c94Snerun        $resized = imagecreatetruecolor($size, $size);
736e2b7c94Snerun        imagefill($resized, 0, 0, $white);
746e2b7c94Snerun        imagecopyresampled($resized, $monster, 0, 0, 0, 0, $size, $size, 120, 120);
75401a61e7Swikidesign        imagedestroy($monster);
766e2b7c94Snerun        return $resized;
77401a61e7Swikidesign    }
782e0c1c6eSGina Haeussge
796e2b7c94Snerun    return $monster;
802e0c1c6eSGina Haeussge}
812e0c1c6eSGina Haeussge
826e2b7c94Snerun/**
836e2b7c94Snerun * Converts part of the hash into an image index
846e2b7c94Snerun */
856e2b7c94Snerunfunction get_part(string $hex, int $min, int $max): int
866e2b7c94Snerun{
876e2b7c94Snerun    $val = hexdec($hex);
886e2b7c94Snerun    return ($val % ($max - $min + 1)) + $min;
89401a61e7Swikidesign}
9023415f0dSnerun
91