RoR - un générateur d'avatars auto-hébergeable en un script

Bon, j'ai un peu tout dit dans le titre... Toutefois, je peux préciser que ce script permet de générer un avatar à partir d'une chaîne de caractères (genre un pseudo, quoi )

Le script utilise les variables $_GET suivantes:

  • str : la chaîne de caractères (obligatoire)
  • sz : la taille souhaitée (par défaut:128)
  • c1 : couleur d'avatar (optionnel, par défaut le script déterminera une couleur en fonction de la chaîne)
  • c2 : pareil que c1 mais pour la couleur de fond.

Du coup Par conséquent, la requête suivante:

index.php?str=Bronco&sz=128&c1=ff0000&c2=00ff00

donnera

avatar généré

et

index.php?str=Bronco

donnera

avatar généré

A noter que lorsque l'avatar est généré, il est sauvegardé dans un dossier avatars/ afin d'éviter de le régénérer à chaque demande.

«Mais comment t'as fait ?» allez-vous me demander d'un ton péremptoire autant que fébrile
Non,non... on s'en fout... en fait.
🗦
PAN
🗦

Donc, le premier problème était d'avoir une pattern pour chaque lettre sur une grille qui ne soit pas trop étendue. Après avoir réfléchi un bon moment, je me suis frappé le front en me disant que la pattern était toute trouvée: l'ordre en binaire de la lettre à encoder...

Second problème, le nombre de lettres et de caractères potentiels m'obligeaient à avoir une grille trop grande (minuscules/majuscules/nombres -> 62 caractères !) 62 en binaire 111110, soient 6 cases x2 pour la symétrie, on se retrouve avec une matrice de 12 x 12... trop à mon goût.

Troisième problème, la taille variable des chaînes potentiellement fournies par l'utilisateur. Il faudrait normaliser ces chaînes avant traitement... pfff.

Illumination: le hash d'une chaîne est toujours de la même longueur... et hash('crc32','blabla'); donne toujours une chaîne de 8 caractères hexadécimaux \o/ : tous les problèmes sont résolus:

  • encodage de 16 caractères (0 à F) : 0000 à 1111.
  • chaîne de longueur fixe quelle que soit les données fournies
    $h1=hash('crc32',$_GET['str']); # pour la génération du dessin et de la couleur 1
    $h2=hash('crc32b',$_GET['str']);#pour la génération de la couleur 2

Il ne reste plus qu'à tracer des carrés de la couleur d'avatar à l'emplacement des 1 et de la couleur de fond à la place des 0.

function drawLine($linenb,$pattern,$size){
    global $image,$couleur_avatar,$couleur_fond;
    for ($i=0;$i<9;$i++){
        $x=$i*$size;
        $y=$linenb*$size;
        if ($pattern[$i]==1){
            imagefilledrectangle ( $image , $x,$y  , $x+$size ,$y+$size , $couleur_avatar );
        }else{
            imagefilledrectangle ( $image , $x,$y  , $x+$size ,$y+$size ,$couleur_fond);
        }
    }
}

Le reste est relativement simple à saisir, je vous mets donc le script complet

<?php 
########################
#                      #
# █████   ████   █████  #
# ██  ██ ██  ██ ██  ██ #
# ██  ██ ██  ██ ██  ██ #
# █████  ██  ██  █████  #
# ██  ██ ██  ██ ██  ██ #
# ██  ██ ██  ██ ██  ██ #
# ██  ██  ████  ██  ██ #
#                      #
########################
# Ror: avatar generator
# @author: bronco@warriordudimanche.net
# howto: use get vars to generate an avatar (once generated, it'll be saved in avatars/ folder)
# ?str=[string] (required)
# ?sz= [integer] avatar's size (opt.) 
# ?c1= [string] avatar's color (opt.)
# ?c2= [string] avatar's background color (opt.)

###############################
#                             #
#  ░░░░  ░   ░░  ░░░░  ░░░░░░ #
#   ░░   ░░  ░░   ░░   ░ ░░ ░ #
#   ░░   ░░░ ░░   ░░     ░░   #
#   ░░   ░░░░░░   ░░     ░░   #
#   ░░   ░░ ░░░   ░░     ░░   #
#   ░░   ░░  ░░   ░░     ░░   #
#  ░░░░  ░░   ░  ░░░░   ░░░░  #
#                             #
###############################

if (!is_dir('avatars')){
    mkdir('avatars');
}
$avatar_filename='';

if (!empty($_GET['c1'])){
    $c1=strip_tags($_GET['c1']);
    $avatar_filename.='-c1='.$c1;
    $c1=separatRGB($c1);
}
if (!empty($_GET['c2'])){
    $c2=strip_tags($_GET['c2']);
    $avatar_filename.='-c2='.$c2;
    $c2=separatRGB($c2);
}
if (!empty($_GET['sz'])){
    $size=intval(strip_tags($_GET['sz']));
}
if (empty($size)){$size=128;}
$avatar_filename='x'.$size.$avatar_filename.'.png';
$dotsize=$size/9;


##################################################################
#                                                                #
# ░░░░░░ ░░  ░░ ░   ░░  ░░░░  ░░░░░░  ░░░░   ░░░░  ░   ░░  ░░░░  #
# ░░     ░░  ░░ ░░  ░░ ░░  ░░ ░ ░░ ░   ░░   ░░  ░░ ░░  ░░ ░░  ░░ #
# ░░     ░░  ░░ ░░░ ░░ ░░       ░░     ░░   ░░  ░░ ░░░ ░░  ░░    #
# ░░░░░  ░░  ░░ ░░░░░░ ░░       ░░     ░░   ░░  ░░ ░░░░░░   ░░   #
# ░░     ░░  ░░ ░░ ░░░ ░░       ░░     ░░   ░░  ░░ ░░ ░░░    ░░  #
# ░░     ░░  ░░ ░░  ░░ ░░  ░░   ░░     ░░   ░░  ░░ ░░  ░░ ░░  ░░ #
# ░░      ░░░░  ░░   ░  ░░░░   ░░░░   ░░░░   ░░░░  ░░   ░  ░░░░  #
#                                                                #
##################################################################

function separatRGB($color){
    $color=str_replace('#','',$color);
    if (strlen($color)==3){
        $color=$color[0].$color[0].$color[1].$color[1].$color[2].$color[2];
    }
    $RGB=array();
    $RGB['r']=hexdec(substr($color, 0,2));
    $RGB['g']=hexdec(substr($color, 2,2));
    $RGB['b']=hexdec(substr($color, 4,2));  
    return $RGB;
}

function drawLine($linenb,$pattern,$size){
    global $image,$couleur_avatar,$couleur_fond;
    for ($i=0;$i<9;$i++){
        $x=$i*$size;
        $y=$linenb*$size;
        if ($pattern[$i]==1){
            imagefilledrectangle ( $image , $x,$y  , $x+$size ,$y+$size , $couleur_avatar );
        }else{
            imagefilledrectangle ( $image , $x,$y  , $x+$size ,$y+$size ,$couleur_fond);
        }
    }
}



###########################################################
#                                                         #
#  ░░░░  ░░░░░░ ░   ░░ ░░░░░░ ░░░░░   ░░░░  ░░░░░░ ░░░░░░ #
# ░░  ░░ ░░     ░░  ░░ ░░     ░░  ░░ ░░  ░░ ░ ░░ ░ ░░     #
# ░░     ░░     ░░░ ░░ ░░     ░░  ░░ ░░  ░░   ░░   ░░     #
# ░░ ░░░ ░░░░░  ░░░░░░ ░░░░░  ░░░░░  ░░░░░░   ░░   ░░░░░  #
# ░░  ░░ ░░     ░░ ░░░ ░░     ░░  ░░ ░░  ░░   ░░   ░░     #
# ░░  ░░ ░░     ░░  ░░ ░░     ░░  ░░ ░░  ░░   ░░   ░░     #
#  ░░░░  ░░░░░░ ░░   ░ ░░░░░░ ░░  ░░ ░░  ░░  ░░░░  ░░░░░░ #
#                                                         #
###########################################################
if (!empty($_GET['str'])){
    $h1=hash('crc32',$_GET['str']);
    $h2=hash('crc32b',$_GET['str']);

    if (empty($c1)){$c1 = separatRGB($h1);}
    if (empty($c2)){$c2 = separatRGB($h2);}

    $s=$h1.$h2[0];
    $file='avatars/'.$s.$avatar_filename;
    if (is_file($file)){
        header ("Content-type: image/png");
        exit(file_get_contents($file));

    }

    $image = @ImageCreate ($size, $size) or die ("Erreur lors de la création de l'image");
    $couleur_fond   = ImageColorAllocate ($image, $c1['r'], $c1['g'], $c1['b']);
    $couleur_avatar = ImageColorAllocate ($image, $c2['r'], $c2['g'], $c2['b']);

    $a[dechex(0)]='000010000';
    $a[dechex(16)]='111111111';

    for ($i=1;$i<=15;$i++){
        $bin=decbin($i);
        $bin=str_repeat('0', 4-strlen($bin)).$bin;
        $a[dechex($i)]=$bin.'1'.strrev($bin);
    }



    for ($i=0;$i<9;$i++){
        drawLine($i,$a[$s[$i]],$dotsize);
    }

    header ("Content-type: image/png");

    ImagePng($image,$file);
    chmod($file,0644);
    ImagePng($image);
}


?>

Le script est téléchargeable ici

✍ Écrire un commentaire

les commentaires relevant du SPAM seront filtrés et dégagés direct...

Quelle est le troisième caractère du mot n163gux ?