JeuWeb - Crée ton jeu par navigateur

Version complète : [PHP - GD] Signatures dynamiques
Vous consultez actuellement la version basse qualité d'un document. Voir la version complète avec le bon formatage.
Il y a quelques temps, j'ai planché sur un module de signature dynamiques pour un site communautaire. Après avoir un peu galérer sur les éléments de texte et beaucoup souffert avec les effets de transparence, je vous livre ici le résultat de mon travail.

Voici une image en PNG qui va me servir de base (elle est tirée du kit pour champion Online et légèrement modifiée pour les besoins de la démonstration).
[Image: bg_1.png]

Sur cette image, je souhaite placer quelques informations.
Dans notre exemple, l'appel se fait de manière simple

Code PHP :
<div style="background-color:lightgreen; float:left;padding:10px;">
<
img src="sign.php5?mode=render"/>
</
div

J'ai mis l'arrière plan en couleur pour faire ressortir la transparence

Voici maintenant le code qui me permettra de générer la signature
Code PHP :
//Inclusion de la classe
require_once './class/signs.class.php5';
$oSign=new Signature();

//Sélection de l'arrière plan. Comme j'utilise un arrière plan en png pour profiter de la transparence, je le précise. dans le 2e paramètre.
$oSign->setBackGround('bg_1','png');

//Ajout des divers éléments de texte
//Classe et niveau
$oTxt=new TextSignature();
$oTxt->setFont('Earth');
$oTxt->setSize(20);
$oTxt->setColor(255,255,255);
$oTxt->setPos(250,165);
$oTxt->setText('Blaster 23');
$oTxt->setShadow(2); // Contour
$oSign->addTextObject($oTxt);

//Nom
$oTxt=new TextSignature();
$oTxt->setFont('Morpheus');
$oTxt->setSize(30);
$oTxt->setColor(128,0,0); // Texte en noir
$oTxt->setPos(260,30);
$oTxt->setText('Justiciar');
$oTxt->setShadow(0); //Pas d'ombre
$oSign->addTextObject($oTxt);

//Texte Perso
$oTxt=new TextSignature();
$oTxt->setFont('Comic Sans MS');
$oTxt->setSize(10);
$oTxt->setColor(255,255,255);
$oTxt->setPos(200,100);
$oTxt->setText('"Le glaive de la justice n\'a pas de fourreau"');
$oTxt->setShadow(1); //Ombre simple
$oSign->addTextObject($oTxt);

//Retour de l'image
$oSign->Render('screen'); 

Enfin, voici le code des deux classes servant de support au générateur de signature

Code PHP :
Class Signature {
    private 
$bgImage='';
    private 
$ext='png';
    private 
$TextObjects=Array();
    private 
$imgBase;
    private 
$mid=0;
    
    function 
setMemberId($id){
        
$this->mid=$id;
    }
    
    function 
setBackGround($img,$type){
        
$this->bgImage=$img;
        
$this->ext=$type;
    }

    function 
addTextObject($o){
        
$this->TextObject[]=$o;
    }
    
    function 
Render($mode){
        
//Récupération de l'image de fond
        
if($this->ext=='png') {
            
$fond=imagecreatefrompng('./signatures/background/'.$this->bgImage.'.png');
        } else if(
$this->ext=='jpg') {
            
$fond=imagecreatefromjpeg('./signatures/background/'.$this->bgImage.'.jpg');
        }
    
        
//Création du canevas de base
        
$this->imgBase=imagecreatetruecolor(imagesx($fond),imagesy($fond));
        
        
//Création du canal Aplha (transparence) sur la base
        
imagealphablending($this->imgBasetrue);
        
        
//Définition de la couleur transparente
        
$transparent imagecolorallocatealpha($this->imgBase000127);
        
        
//Remplissage du fond en transparent
        
imagefill($this->imgBase00$transparent);
        
        
//Sauvegarde du canal Alpha
        
imagesavealpha($this->imgBase,true);
        
        
//Copie du fond sur la base
        
imagecopy($this->imgBase$fond00,  00imagesx($fond), imagesy($fond));

        
//Ajout des éléments de texte
        
foreach($this->TextObject as $o){
            
$this->insertTextObject($o);
        }

        
//Sauvegarde du résultat
        
header('Content-Type: image/png');
        if(
$mode=='disk'){
            
imagepng($this->imgBase,'signatures/members/'.$this->mid.'.png');
        } else {
            
imagepng($this->imgBase);
        }
        
//Supression des objets
        
imagedestroy($fond);
        
imagedestroy($this->imgBase);
    }
    
    function 
insertTextObject($o){
        
//L'insertion d'un text object se fait en deux temps
        //- Création de l'ombre si nécessaire
        //- Positionnement du texte proprement dit
        
if($o->getProperty('Shadow')==1){
            
//Appel de la fonction ajoutant un élément avec un offset simple
            
$this->insertTextElement($o,'Shadow',1,1);
        } elseif(
$o->getProperty('Shadow')==2){
            
//Contour
            //Appel multiple de la fonction ajoutant un élément avec 
            //un offset différent à chaque fois pour créer le contour
            
$this->insertTextElement($o,'Shadow',-1,-1);
            
$this->insertTextElement($o,'Shadow'0,-1);
            
$this->insertTextElement($o,'Shadow'1,-1);
            
$this->insertTextElement($o,'Shadow',-1);
            
$this->insertTextElement($o,'Shadow'10);
            
$this->insertTextElement($o,'Shadow',-11);
            
$this->insertTextElement($o,'Shadow'01);
            
$this->insertTextElement($o,'Shadow'11);
        }
        
//Ajout de l'élément text principal
        
$this->insertTextElement($o);
    }

    function 
insertTextElement($o,$s='',$ox=0,$oy=0){
        
//Préparation de la TTFBox pour le texte
        
$bbox=imagettfbbox($o->getProperty('Size'),0,'signatures/fonts/'.$o->getProperty('Font').'.ttf',$o->getProperty('Text'));
        
$width abs($bbox[2] - $bbox[0])+2;
        
$height abs($bbox[5] - $bbox[3]);
        
//Création du canevas pour le texte
        
$imgtext imageCreateTrueColor($width$height);
        
        
//Récupération des paramètres du texte via GetProperty
        
$aCol=$o->getProperty($s.'Color');
        
$aPos=$o->getProperty('Pos');
        
        
//Passage en mode Alpha
        
ImageAlphaBlending($imgtexttrue);
        
imageSaveAlpha($imgtexttrue);
        
        
//Création de la couleur transparente
        
$trs imagecolorallocatealpha($imgtext$aCol['r'], $aCol['v'], $aCol['b'], 127);
    
        
//Remplissage en couleur transparente
        
imagefill($imgtext00$trs);
    
        
//Affectation de la couleur du texte
        
$col imagecolorallocate($imgtext$aCol['r'], $aCol['v'], $aCol['b']);
        
//Génération du texte avec la bonne couleur
        
imagettftext($imgtext$o->getProperty('Size'), 00abs($bbox[5])-1$col'signatures/fonts/'.$o->getProperty('Font').'.ttf',$o->getProperty('Text'));
        
        
//Copye sur le canevas générique de la signature
        
imagecopy($this->imgBase$imgtext$aPos['x']+$ox$aPos['y']+$oy,  00imagesx($imgtext), imagesy($imgtext));
        
        
//Suppression de l'objet
        
imagedestroy($imgtext);
    }
        
}

Class 
TextSignature {
    
//Classe permettant de créer les divers éléments de texte.
    
Private $aProp=Array(
        
'Font'=>'Comic Sans MS',
        
'Size'=>'10',
        
'Color'=>array('r'=>255,'v'=>255,'b'=>255),
        
'Pos'=>array(0,0),
        
'Text'=>'text',
        
'Shadow'=>1,
        
'ShadowColor'=>array('r'=>0,'v'=>0,'b'=>0)
    );
    
    function 
setFont($f){
        
//Police à utiliser
        
$this->aProp['Font']=$f;
    }
    
    function 
setSize($s){
        
//Taille de la police
        
$this->aProp['Size']=$s;
    }
    
    function 
setColor($r,$v,$b){
        
//Couleur du texte
        
$this->aProp['Color']=array('r'=>$r,'v'=>$v,'b'=>$b);
    }
    
    function 
setPos($x,$y){
        
//Position du texte
        
$this->aProp['Pos']=array('x'=>$x,'y'=>$y);
    }
    
    function 
setText($t){
        
//Contenu du texte
        
$this->aProp['Text']=$t;
    }
    
    function 
setShadow($i){
        
//Type d'ombre sur le texte
        //0 = aucune
        //1 = Ombre simple
        //2 = Contour
        
$this->aProp['Shadow']=$i;
    }
    
    function 
setShadowColor($r,$v,$b){
        
//Couleur à appliquer sur l'ombre
        
$this->aProp['ShadowColor']=array('r'=>$r,'v'=>$v,'b'=>$b);
    }
    
    function 
getProperty($s){
        
//Fonction permettant de récupérer une propriété de l'objet
        
return $this->aProp[$s];
    }


Dans l'exemple, les informations sont toutes codées en "dur" dans PHP mais c'est facilement adaptable à une structure de bases de données ou à un passage de paramètres dans l'URL,l'essentiel étant bien sur de rendre tout cela dynamique.

Le gros avantage du ystème est qu'il est possible d'utiliser n'importe quelle font True Type pour générer le texte.
Dans mon cas, je les ai stockées dans le dossier ./signatures/fonts. Attention cependant, certaines fonts ne supportent pas les caractères accentués.

Sur mon site, je génère les signatures pour chaque membre dans un dossier spécifique.
Lorsque le profil de ce membre change, la signature est alors mise à jour et sauvegardée à nouveau.
Cela évite l'appel à GD à chaque fois que quelqu'un consulte une signature.

Voici donc le résultat de l'appel des classes de signature avec les paramètres donnés en exemple (génération via GD à la volée).

Et voici la copie sauvegardée au format PNG du résultat

[Image: 117.png]
merci pour le partage 34
me pencherai dessus pour une petite idée 34
C'est vrai que c'est super chouette !

Kéké qui a trop de choses à faire pour rajouter un n'ieme point...
Sympa de partager une ressource, ça peut servir en tant que tel mais aussi à titre d'exemple d'utilisations diverses qu'on peut faire avec GD pour ceux qui voudraient se lancer mais qui se sentent perdus.

Nice job !
Merci,il y a quelques temps je m'étais intéressé à propos des signatures dynamiques!
URLs de référence