1#!/usr/bin/php
2<?php
3// -*- coding: utf-8 -*-
4declare(strict_types=1);
5
6// Avatar parameters
7define('IMG_SIZE', 120);
8define('ROUNDS', 20000);
9define('PARTS_DIR', __DIR__ . '/parts');
10
11$partGroups = [
12    'arms'  => 5,
13    'body'  => 15,
14    'eyes'  => 15,
15    'hair'  => 5,
16    'legs'  => 5,
17    'mouth' => 10,
18];
19
20function getRandomPart(string $group, int $max): GdImage {
21    $n = random_int(1, $max);
22    $path = sprintf('%s/%s_%d.png', PARTS_DIR, $group, $n);
23    return imagecreatefrompng($path);
24}
25
26function generateMonster(): GdImage {
27    $img = imagecreatetruecolor(IMG_SIZE, IMG_SIZE);
28    imagesavealpha($img, true);
29    $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
30    imagefill($img, 0, 0, $transparent);
31
32    global $partGroups;
33    foreach ($partGroups as $group => $count) {
34        $part = getRandomPart($group, $count);
35        imagecopy($img, $part, 0, 0, 0, 0, IMG_SIZE, IMG_SIZE);
36        imagedestroy($part);
37    }
38    return $img;
39}
40
41// Run benchmark
42$sizes = [];
43for ($i = 0; $i < ROUNDS; $i++) {
44    $img = generateMonster();
45    ob_start();
46    imagepng($img, null, 9);
47    $data = ob_get_clean();
48    $sizes[] = strlen($data);
49    imagedestroy($img);
50}
51
52// Statistics
53$min = min($sizes);
54$max = max($sizes);
55$avg = array_sum($sizes) / count($sizes);
56$stddev = sqrt(array_sum(array_map(fn($s) => pow($s - $avg, 2), $sizes)) / count($sizes));
57
58printf("Generated avatars: %d\n", ROUNDS);
59printf("Minimum size: %.2f KB\n", $min / 1024);
60printf("Maximum size: %.2f KB\n", $max / 1024);
61printf("Average size: %.2f KB\n", $avg / 1024);
62printf("Standard deviation: %.2f KB\n", $stddev / 1024);
63
64