xref: /plugin/avatar/monsterid.php (revision 6e2b7c9463eb828aa4f99eb98fdced23ba7cc437) !
1401a61e7Swikidesign<?php
21affe9b7Swikidesign/**
3*6e2b7c94Snerun * MonsterID Generator for DokuWiki Avatar Plugin
4*6e2b7c94Snerun *
5*6e2b7c94Snerun * Generates identicon-style monster avatars based on a seed.
6*6e2b7c94Snerun * Requires PHP GD extension.
7*6e2b7c94Snerun *
81affe9b7Swikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
91affe9b7Swikidesign * @author  Andreas Gohr <andi@splitbrain.org>
10*6e2b7c94Snerun * @author  Daniel Dias Rodrigues <danieldiasr@gmail.com> (modernization)
111affe9b7Swikidesign */
12401a61e7Swikidesign
13*6e2b7c94Snerundeclare(strict_types=1);
14*6e2b7c94Snerun
15*6e2b7c94Snerunif (php_sapi_name() !== 'cli') {
16*6e2b7c94Snerun    $seed = preg_replace('/[^a-f0-9]/i', '', $_GET['seed'] ?? '');
17*6e2b7c94Snerun    $size = (int) ($_GET['size'] ?? 120);
18*6e2b7c94Snerun    $size = max(20, min(512, $size)); // limits between 20 and 512 pixels
19*6e2b7c94Snerun
20*6e2b7c94Snerun    header('Content-Type: image/png');
21*6e2b7c94Snerun    header('Cache-Control: public, max-age=86400');
22*6e2b7c94Snerun
23*6e2b7c94Snerun    $image = generate_monster($seed, $size);
24*6e2b7c94Snerun    if ($image) {
25*6e2b7c94Snerun        imagepng($image);
26*6e2b7c94Snerun        imagedestroy($image);
27*6e2b7c94Snerun    } else {
28*6e2b7c94Snerun        http_response_code(500);
29*6e2b7c94Snerun        echo 'Erro ao gerar imagem.';
30*6e2b7c94Snerun    }
31*6e2b7c94Snerun    exit;
32*6e2b7c94Snerun}
33401a61e7Swikidesign
341affe9b7Swikidesign/**
35*6e2b7c94Snerun * Generates monster image based on seed and size
361affe9b7Swikidesign */
37*6e2b7c94Snerunfunction generate_monster(string $seed, int $size): ?GdImage
38*6e2b7c94Snerun{
39*6e2b7c94Snerun    if (!function_exists('imagecreatetruecolor')) {
40*6e2b7c94Snerun        return null;
41*6e2b7c94Snerun    }
42*6e2b7c94Snerun
432e0c1c6eSGina Haeussge    $hash = md5($seed);
44401a61e7Swikidesign
45*6e2b7c94Snerun    $parts = [
46*6e2b7c94Snerun        'legs'  => get_part(substr($hash, 0, 2), 1, 5),
47*6e2b7c94Snerun        'hair'  => get_part(substr($hash, 2, 2), 1, 5),
48*6e2b7c94Snerun        'arms'  => get_part(substr($hash, 4, 2), 1, 5),
49*6e2b7c94Snerun        'body'  => get_part(substr($hash, 6, 2), 1, 15),
50*6e2b7c94Snerun        'eyes'  => get_part(substr($hash, 8, 2), 1, 15),
51*6e2b7c94Snerun        'mouth' => get_part(substr($hash, 10, 2), 1, 10),
52*6e2b7c94Snerun    ];
53401a61e7Swikidesign
54*6e2b7c94Snerun    $monster = imagecreatetruecolor(120, 120);
55*6e2b7c94Snerun    if (!$monster) return null;
56*6e2b7c94Snerun
57401a61e7Swikidesign    $white = imagecolorallocate($monster, 255, 255, 255);
58401a61e7Swikidesign    imagefill($monster, 0, 0, $white);
59401a61e7Swikidesign
60*6e2b7c94Snerun    foreach ($parts as $part => $index) {
61*6e2b7c94Snerun        $filename = __DIR__ . '/parts/' . $part . $index . '.png';
62*6e2b7c94Snerun        if (!file_exists($filename)) continue;
63*6e2b7c94Snerun        $part_img = imagecreatefrompng($filename);
64*6e2b7c94Snerun        if ($part_img) {
65*6e2b7c94Snerun            imagecopy($monster, $part_img, 0, 0, 0, 0, 120, 120);
66*6e2b7c94Snerun            imagedestroy($part_img);
67401a61e7Swikidesign        }
68401a61e7Swikidesign    }
69401a61e7Swikidesign
70*6e2b7c94Snerun    if ($size !== 120) {
71*6e2b7c94Snerun        $resized = imagecreatetruecolor($size, $size);
72*6e2b7c94Snerun        imagefill($resized, 0, 0, $white);
73*6e2b7c94Snerun        imagecopyresampled($resized, $monster, 0, 0, 0, 0, $size, $size, 120, 120);
74401a61e7Swikidesign        imagedestroy($monster);
75*6e2b7c94Snerun        return $resized;
76401a61e7Swikidesign    }
772e0c1c6eSGina Haeussge
78*6e2b7c94Snerun    return $monster;
792e0c1c6eSGina Haeussge}
802e0c1c6eSGina Haeussge
81*6e2b7c94Snerun/**
82*6e2b7c94Snerun * Converts part of the hash into an image index
83*6e2b7c94Snerun */
84*6e2b7c94Snerunfunction get_part(string $hex, int $min, int $max): int
85*6e2b7c94Snerun{
86*6e2b7c94Snerun    $val = hexdec($hex);
87*6e2b7c94Snerun    return ($val % ($max - $min + 1)) + $min;
88401a61e7Swikidesign}
8923415f0dSnerun
90