Met ton masque de transparence avec PHP et GD2
Par nod le 01 septembre 2007, - tuto - Lien permanent
Introduction
Le but du jeu c’est de produire une image sans transparence avec une couleur de fond et une forme de couleur unie par dessus, comme ici

Le tout à partir d’une image ayant des parties transparentes et un motif avec des photos, comme ici

La méthode
La démarche est simple, créer une nouvelle image, la remplir de la couleur de fond choisie, et mettre par dessus le png transparent du début en remplaçant les images par une couleur unie.
Pas à Pas
Préparation des images
Première étape on charge le png transparent avec les images
$template = imagecreatefrompng('masque_avec_images.png');
imagealphablending($template, false);
La fonction imagealphablending() permet de garder les informations du canal alpha (la transparence pour les noobs) lors de l'utilisation des fonctions de dessin.
$width = imagesx($template);
$height = imagesy($template);
On récupère la largeur et la hauteur de l'image pour la création de l'image finale.
$img = imagecreatetruecolor($width, $height);
imagealphablending($img, true);
$background = imagecolorallocate ($img, 140, 20, 40);
imagefill($img,0,0,$background);
Rien de mystérieux. Cette fois ci on utilise l'alphablending, ce qui signifie que lors de l'utilisation des fonctions de dessin le résultat final sera opaque, le canal alpha n'existera plus (l'image de sortie pouvant être jpeg par exemple). On alloue la couleur de fond avec imagecolorallocate() et on remplit la nouvelle image de cette couleur. Les images sont chargés et prêtes à être utilisé.
FUSION !
Maintenant la partie un peu technique. Les images sont en mémoires, on veut
une image avec une couleur unie (blanche ici) possédant le canal alpha de
l'image $template pour ensuite la fusionner à l'image avec la
couleur de fond $img.
for ($i=0; $i < $width; ++$i) {
for ($j=0; $j < $height; ++$j) {
$pxl_alpha = imagecolorsforindex (
$template,
imagecolorat ($template, $i, $j));
$color = array ('red'=>255,
'green'=>255,
'blue'=>255);
$ctmp = imagecolorallocatealpha (
$img,
$color['red'],
$color['green'],
$color['blue'],
$pxl_alpha['alpha']);
imagesetpixel ($img, $i, $j, $ctmp);
}
}
Les deux images étant de la même taille, on parcours les deux pixel par
pixel. On récupère les informations du pixel à l'index en cours avec imagecolorat() et
on transforme la valeur de retour en un truc exploitable avec imagecolorsforindex().
La valeur d'alpha que l'on veux est contenu dans $pxl_alpha['alpha']. On alloue la couleur avec la valeur de
l'alpha que l'on vient de récupérer. Pour finir on dessine le pixel sur l'image
final $img. La valeur de l'alpha varie de 127 à 0, respectivement
pour la transparence et l'opacité.
Envoi
L'image est prête, reste plus qu'a l'envoyer.
header ("Content-type: image/jpg");
imagejpeg ($img);
imagedestroy ($template);
imagedestroy ($img);
Comme on à été bien élevé, on fait le ménage quand on à fini, et magie !

Et après ?
Les limites de ce magnifique script sont nombreuses, les deux images ont la même taille, la couleur de remplacement est unie.
Crédits
Ce tuto est fait à partir de Manipulation d'images avec php de chez xgarreau.org. Un autre article bien sympa de chez developpez.com La manipulation d'images avec PHP : librairie GD.
Le code
Le code complet pour les oufs du copier, coller.
/*
Préparation des images
*/
$template = imagecreatefrompng('masque_avec_images.png');
imagealphablending($template, false);
$width = imagesx($template);
$height = imagesy($template);
$img = imagecreatetruecolor($width, $height);
imagealphablending($img, true);
$background = imagecolorallocate ($img, 140, 20, 40);
imagefill($img,0,0,$background);
/*
FUSION !
*/
for ($i=0; $i < $width; ++$i) {
for ($j=0; $j < $height; ++$j) {
$pxl_alpha = imagecolorsforindex (
$template,
imagecolorat ($template, $i, $j));
$color = array ('red'=>255,
'green'=>255,
'blue'=>255);
$ctmp = imagecolorallocatealpha (
$img,
$color['red'],
$color['green'],
$color['blue'],
$pxl_alpha['alpha']);
imagesetpixel ($img, $i, $j, $ctmp);
}
}
/*
Envoi
*/
header ("Content-type: image/jpg");
imagejpeg ($img);
imagedestroy ($template);
imagedestroy ($img);