GenPic: un générateur d'images aléatoires (ou pas)

Tiens, je pensais avoir déjà parlé de ce petit script réalisé lors d'une de mes multiples digressions... ben en fait... non (je pense que j'attendais d'être sûr qu'il n'y a plus de bugs :D ). Donc, voilà.

GenPic permet de générer des images selon un certain nombre de paramètres (taille, motifs, répartition, couleurs etc).

On peut l'utiliser en spécifiant chaque paramètre ou bien n'en spécifier que certains... voire aucun (on obtient donc une image entièrement aléatoire)

image image image image image

Le script est utilisable là: http://genpic.warriordudimanche.net/ et récupérable en mode do what you want sur github (non, je ne l'ai pas quitté: la flemme)

Ci-dessous, une galerie d'images générées par le script. (...)

Lire la suite de GenPic: un générateur d'images aléatoires (ou pas)

Plugin pluXML: ROR-le-plugin

Après le script d'hier, permettant de générer un avatar via une «API» simple, j'ai bricolé un plugin pour pluXML qui se charge de la même chose.

Comme la version standalone, ROR le plugin crée un avatar (ou charge un avatar déjà créé) sur l'appel du hook

eval($plxShow->callHook("showAvatar"));


J'ai toutefois ajouté une page de config pour pouvoir en affiner le comportement.

image

On peut spécifier:

  • la taille en px de l'avatar généré
  • les couleurs de premier plan et d'arrière plan (si on souhaite que les avatars s'accordent à un design)
  • le nom de l'admin, au cas où -comme c'est mon cas- vous voulez que l'admin ait un avatar différent.
  • le code html correspondant à l'avatar des visiteurs et celui pour l'avatar de l'admin (ce qui éviter d'aller mettre les doigts dans le code) (ce n'est pas sale) (#DSL )

Donc, vous pourrez modifier le script themes/VOTRETHEME/commentaires.php pour ajouter le hook comme suit:

<div id="<?php $plxShow->comId(); ?>" class="comment <?php $plxShow->comLevel(); ?>">
    <?php eval($plxShow->callHook("showAvatar")) ?> # <--- c'est là 
    <div id="com-<?php $plxShow->comIndex(); ?>" class="<?php $plxShow->comAuthor(); ?>">

Allez dans l'épais du saigneur pis tout ça...

GitHub - broncowdd/pluxml-plugin-generator: Une appli pour générer les fichiers et le dossier d'un plugin, le tout préconfiguré et prêt à coder.

Juste un mot en passant pour annoncer une maj de mon générateur de plugin pour pluxml (v0.9)
Ajouts:

  • ajout des paramètres de config dans les propriétés de la classe (private)
  • ajout de la récupération des valeurs de variables de config dans le constructeur de la classe
  • ajout des index "nom_de_parametre" dans le fichier de langue
  • ajout de la traduction des noms de parametre dans la page de config
  • ajout de l'icône du plugin dans la page de config
  • petits changements cosmétiques dans la page de config.

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

Lire la suite de RoR - un générateur d'avatars auto-hébergeable en un script

Getlib: ramener des bibliotheques & frameworks en local en une ligne

Certains se souviennent peut-être de goofi, pour récupérer des google fonts en local; sur la base de ce script, j'ai bricolé une version qui permettra de faire la même chose avec les bibliothèques et frameworks (notamment js) que tout un chacun utilise et dont l'appel participe aux stats de google et consorts à chaque requête sur leur serveur.

Donc, en gros, il suffit de remplacer l'appel du script dans le en ajoutant getlib.php?url= devant.

Ainsi

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

deviendra

<script src="http://www.warriordudimanche.net/getlib.php?url=https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Le fichier est récupéré une seule fois et seule la vertsion locale sera renvoyée par la suite.

Au cas où vous voulez que le script récupère une éventuelle mise à jour, il suffit d'ajouter update dans l'url:

<script src="http://www.warriordudimanche.net/getlib.php?update&url=https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Getlib vérifiera alors si le fichier distant a changé et le retéléchargera si c'est nécessaire.

Comme avec Goofi, seule l'IP du serveur qui héberge le script est connue du serveur distant, jamais celle du visiteur.

C'est tout! Je n'ai pas testé à fond encore et les erreurs ne sont pas gérées pour le moment, mais ça fonctionne quand même pas mal !

<?php 
# get libs from distant servers to local (& avoid unnecessary requests to servers who can log user's connections)
# ex:  
# https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
# becomes
# getlib.php?url=https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
# if you want to update local file if the distant one changes, just add "update" 
# getlib.php?update&url=https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
# author: warriordudimanche.net
# 
$lib_folder='libs/';
$check_updates=isset($_GET['update']);

if (!empty($_GET['url'])){
    if (!is_dir($lib_folder)){mkdir($lib_folder);}

    $url=strip_tags($_GET['url']);
    $local_filename=$lib_folder.basename($url);
    $flag='non';
    if (
        !is_file($local_filename)
        ||
        ($check_updates && !isSameFile())

    ){
        $lib=file_get_contents($url);
        file_put_contents($local_filename,$lib);
        $head = array_change_key_case(get_headers($url, TRUE));
        file_put_contents($local_filename.'.info', $head['last-modified']);
        $flag='oui';
    }
    header('Content-Type: '.mime_content_type($local_filename));
    exit(file_get_contents($local_filename));
}

function getDistantFile($url){
    global $local_filename;
    $lib=file_get_contents($url);
    file_put_contents($local_filename,$lib);
    $head = array_change_key_case(get_headers($url, TRUE));
    file_put_contents($local_filename.'.info', $head['last-modified']);
}

function isSameFile(){
    global $local_filename,$url;
    $head = array_change_key_case(get_headers($url, TRUE));
    $local=file_get_contents($local_filename.'.info');
    $distant=$head['last-modified'];
    return $distant==$local;
}

getlib.zip le dépôt

Comme toujours,
c'est aux autres de débugger
les scripts que tu commets, heu... commit...
super.
🗦
Et je vais t'avouer un truc, j'ai même pas honte !
C'est même ma marque de fabrique: une genre de «Bronco's touch»

Fil RSS des articles de ce mot clé