JeuWeb - Crée ton jeu par navigateur
[PHP - GD] Signatures dynamiques - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [PHP - GD] Signatures dynamiques (/showthread.php?tid=4084)



[PHP - GD] Signatures dynamiques - Roworll - 12-06-2009

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 :
<?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 :
<?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 :
<?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->imgBase, true);

//Définition de la couleur transparente
$transparent = imagecolorallocatealpha($this->imgBase, 0, 0, 0, 127);

//Remplissage du fond en transparent
imagefill($this->imgBase, 0, 0, $transparent);

//Sauvegarde du canal Alpha
imagesavealpha($this->imgBase,true);

//Copie du fond sur la base
imagecopy($this->imgBase, $fond, 0, 0, 0, 0, imagesx($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, 0 );
$this->insertTextElement($o,'Shadow', 1, 0);
$this->insertTextElement($o,'Shadow',-1, 1);
$this->insertTextElement($o,'Shadow', 0, 1);
$this->insertTextElement($o,'Shadow', 1, 1);
}
//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($imgtext, true);
imageSaveAlpha($imgtext, true);

//Création de la couleur transparente
$trs = imagecolorallocatealpha($imgtext, $aCol['r'], $aCol['v'], $aCol['b'], 127);

//Remplissage en couleur transparente
imagefill($imgtext, 0, 0, $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'), 0, 0, abs($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, 0, 0, imagesx($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]


RE: [PHP - GD] Signatures dynamiques - Ruz - 12-06-2009

merci pour le partage ^^
me pencherai dessus pour une petite idée ^^


RE: [PHP - GD] Signatures dynamiques - keke - 12-06-2009

C'est vrai que c'est super chouette !

Kéké qui a trop de choses à faire pour rajouter un n'ieme point...


RE: [PHP - GD] Signatures dynamiques - Allwise - 12-06-2009

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 !


RE: [PHP - GD] Signatures dynamiques - Nodark - 13-06-2009

Merci,il y a quelques temps je m'étais intéressé à propos des signatures dynamiques!