06-12-2009, 11:50 AM
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]](http://90plan.ovh.net/~furiesin/tutos/signatures/background/bg_1.png)
Sur cette image, je souhaite placer quelques informations.
Dans notre exemple, l'appel se fait de manière simple
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
Enfin, voici le code des deux classes servant de support au générateur de signature
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]](http://90plan.ovh.net/~furiesin/tutos/signatures/members/117.png)
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]](http://90plan.ovh.net/~furiesin/tutos/signatures/background/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->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]](http://90plan.ovh.net/~furiesin/tutos/signatures/members/117.png)