Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zér0 > Les tutoriels > Non-Officiels > Site Web > PHP > Langage, bibliothèques et fonctions > Lecture du tutoriel

[GD] Créer des gifs animés avec PHP

Avatar
Auteur : Phoenix76
Créé : le 20/02/2008 14:07:56
Modifié : le 21/04/2008 16:31:17
Noter et commenter ce tutoriel
Imprimer ce tutoriel
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Bonjour et bienvenue dans ce tutoriel !

La librairie GD offre de nombreuses possibilités pour manipuler vos images : cependant, une manque cruellement : l'animation. Pourtant, vous aimeriez bien ajouter de petits effets à vos images. Mais vous avez eu beau chercher une solution, rien de bien concluant.
Vous croyiez que tout était perdu ? Eh bien oui erreur : Phoenix76 est là et ensemble, nous allons pouvoir défiger GD.

Prêts ? À l'attaaaaque ! :pirate:

Pour bien comprendre ce tutoriel, vous devez avoir lu l'ensemble du tutoriel officiel sur le PHP.
Il y aura quelques notions que vous n'aurez certainement pas vues, mais pas de panique : elles seront toutes expliquées. ;)

Niveau : 5/10 - Intermédiaire.
Sommaire du chapitre :

Les bases

C'est quoi, un gif animé ?



Le gif animé est une amélioration du format GIF, apparue en 1989. Il permet de stocker une succession d'images auxquelles est associé un temps d'affichage. Autrement dit, il permet d'obtenir une animation.

La classe magique



GD permet de créer des gif simples : donc, si l'on suit la définition, il suffirait de "coller" plusieurs gif entre eux pour obtenir une belle animation. Malheureusement, regrouper des images entre elles n'est pas chose facile, GD en est même incapable. Mais n'ayez crainte, László Zsidi a développé une classe comblant cette petite lacune : GIFEncoder (cliquez ici pour la télécharger).

Une classe permet de créer des objets contenant un ensemble de fonctions (les méthodes) et de variables (les attributs).
Ici la classe GIFEncoder permet de créer des objets "gif animés" avec lesquels on peut interagir, via des méthodes comme GetAnimation() pour obtenir notre animation.
Si vous vous voulez en savoir plus sur la POO et tout ce qui en découle (les classes, les méthodes...), direction Wikipédia.

Squelette du script

Vous l'aurez sûrement deviné : dans cette partie, nous établirons une base pour vos futures créations.

Tout d'abord, on va importer notre classe :
Code : PHP
1
2
3
<?php
require('libs/gif.class.php');
?>

J'ai l'habitude de placer mes classes dans un dossier libs ; vous n'êtes pas obligés de le faire, le principal est que vous puissiez vous y retrouver. :p

Bon : maintenant, on reprend notre définition : "une succession d'images auxquelles sont associé un temps d'affichage". Comment peut-on traduire ça en PHP ? Avec des tableaux, pardi. ^^
Code : PHP
1
2
3
4
<?php
$animation = array(); //Chaque élément de ce tableau sera une image...
$duree = array(); //...avec une durée associée
?>

On peut maintenant créer nos images :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
$image = imagecreate(LARGEUR, HAUTEUR); //constantes à définir
//À vous de jouer avec les couleurs, les formes...
//On place l'image dans notre tableau animation
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
$duree[] = X; //Attention, le temps d'affichage des images s'écrit en ms
 
//On détruit la dernière image pour libérer de la mémoire
imagedestroy($image);
?>

Vous vous demandez sûrement à quoi servent les fonctions ob_start() et ob_get_clean(). Plutôt que de faire un long discours abstraits, nous verrons leur rôle dans la partie pratique. Retenez pour l'instant que les 3 lignes surlignées placent notre image dans le tableau animation. ;)

Bon, ça avance bien, on a deux tableaux avec nos images et durées d'affichage. On n'a plus qu'à tout coller. :)
Code : PHP
1
2
3
<?php
$gif = new GIFEncoder($animation, $duree, 0, 2, 0, 0, 0, "bin");
?>

On crée un objet gif en fonction de l'ensemble de nos images et de leur temps d'affichage grâce à la méthode GIFEncoder. L'objet gif contient désormais notre animation.

On peut remplir $animation soit avec des images générées avec GD, soit avec des fichiers images déjà existants. En fonction du type des images, on adapte le dernier paramètre : dans le premier cas c'est bin, dans le deuxième url. Les trois avant-derniers paramètres permettent de rajouter de la couleur à des gif transparents suivant le codage rgb.

C'est fini, alors ? Non, il reste à afficher l'image ou à l'enregistrer. Pour ce faire, on va utiliser une autre méthode de notre classe : GetAnimation. Elle retourne notre image sous forme de chaîne de caractères.

Donc, pour afficher on fait :
Code : PHP
1
2
3
4
<?php
header('Content-type: image/gif'); //Indique au navigateur qu'on veut afficher une image gif et non pas des caractères
echo $gif->GetAnimation();
?>

Et pour enregistrer (revoir le cours sur les fichiers) :
Code : PHP
1
2
3
4
5
<?php
$fichier = fopen('VOTRE_IMAGE.gif', 'w+');
fputs($fichier, $gif->GetAnimation());
fclose($fichier);
?>


Notre squelette finalisé



Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
require('libs/gif.class.php');
$animation = array(); //Chaque élément de ce tableau sera une image...
$duree = array(); //...avec une durée associée
 
//On crée les différentes images de l'animation et on définit leur temps affichage
$image = imagecreate(LARGEUR, HAUTEUR);
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
$duree[] = 100; //Attention, le temps d'affichage des images s'écrit en ms
 
//On détruit la dernière image pour libérer de la mémoire
imagedestroy($image);
 
//On crée le gif à partir de l'animation
$gif = new GIFEncoder($animation, $duree, 0, 2, 0, 0, 0, "bin");
 
//On affiche 
header('Content-type: image/gif'); //Indique au navigateur qu'on veut afficher une image gif et non pas des caractères
echo $gif->GetAnimation();
 
//Ou on enregistre
$fichier = fopen('VOTRE_IMAGE.gif', 'w+');
fputs($fichier, $gif->GetAnimation());
fclose($fichier);
?>

Exemples

Une bannière



Aperçu : Image utilisateur

Bon, c'est moche, ça ne sert à rien et vous auriez pu le faire en 10 secondes avec n'importe quel logiciel ; mais j'ai fait cette partie pour que vous compreniez bien le principe. ;) Comme vous pouvez le constater, cette animation est composée de deux images : une de fond rouge, l'autre de fond bleu avec un texte identique de couleur blanche. Le temps d'affichage des images est de 1 seconde.

Première chose à faire : on reprend notre squelette.
Ensuite, on définit un message et des dimensions qui lui sont adaptées :
Code : PHP
1
2
3
4
5
<?php
$largeur = 210;
$hauteur = 25;
$message = 'Mon premier gif en php';
?>

On peut maintenant passer à la création de la première image :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
$image = imagecreate($largeur, $hauteur);
$fond = imagecolorallocate($image, 255, 0, 0);
$blanc = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 5, 5, 5, $message, $blanc);
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
$duree[] = 100; //Les durées doivent être en ms, 1s <=> 100ms
imagedestroy($image);
?>

Si vous ne comprenez pas tout, allez revoir le cours sur GD.
Je vous laisse créer la deuxième image. ;)

Vous avez fini ? Bien : vous devriez avoir quelque chose qui ressemble à ceci :
Secret (cliquez pour afficher)

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
require('libs/gif.class.php');
$animation = array();
$duree = array();
 
$largeur = 210;
$hauteur = 25;
$message = 'Mon premier gif en php';
 
$image = imagecreate($largeur, $hauteur);
$fond = imagecolorallocate($image, 255, 0, 0);
$blanc = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 5, 5, 5, $message, $blanc);
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
$duree[] = 100;
imagedestroy($image);
 
$image = imagecreate($largeur, $hauteur);
$fond = imagecolorallocate($image, 0, 0, 255);
$blanc = imagecolorallocate($image, 255, 255, 255);
imagestring($image, 5, 5, 5, $message, $blanc);
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
$duree[] = 100;
imagedestroy($image);
 
$gif = new GIFEncoder($animation, $duree, 0, 2, 0, 0, 0, "bin");
header ("Content-type: image/gif");
echo $gif->GetAnimation();
?>



Et voilà : normalement, une belle image s'affiche sous vos yeux ébahis. ^^ Nous pouvons maintenant passer à la seconde partie.
Hé minute, tu ne nous as toujours pas expliqué à quoi servait ob_start() et ob_get_clean() !

Ah oui, quel étourdi ! :-°
Bon, comme l'apprentissage passe par la pratique, enlevez-moi ces deux fonctions :

Code : PHP
1
2
3
4
5
<?php
ob_start();
imagegif($image);
$animation[] = ob_get_clean();
?>

Devient :
Code : PHP
1
2
3
<?php
$animation[] = imagegif($image);
?>

Actualisez votre page et... un tas de caractères bizarres apparaissent o_O . Pas de panique : c'est tout à fait normal. En effet, la fonction imagegif renvoie notre image sous la forme d'une chaine de caractères. Comme nous n'avons pas indiqué au navigateur que l'on voulait afficher cette chaine sous la forme d'une image (avec un header), ça bidouille. :D
Pour éviter ce petit désagrément, on va stocker nos caractères dans un tampon grâce à ob_start(). Ce tampon est particulier : les informations qu'il contient ne sont pas transmises au navigateur. Maintenant, on vide le contenu du tampon dans notre tableau animation grâce à ob_get_clean(). Le tampon est également supprimé, rien n'est transmis au navigateur, donc, rien ne s'affiche. Par contre, notre tableau contient dorénavant notre image. :magicien:
Pour les sceptiques, vérifiez avec un echo.

Exercices supplémentaires (par ordre de difficulté croissante)



Un flux RSS en image



Objectif : réaliser une image pour indiquer sur les forums les dernières news de son site.

Aperçu : Image utilisateur

Pour cette partie, je vais vous donner quelques indications et ce sera à vous de jouer. ;)

Tout d'abord, récupérez l'image d'arrière-plan (généreusement fournie par Jerry Wham), ou créez votre propre image.

Pour que tout le monde ait la même base, créez une nouvelle table :
Code : SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
CREATE TABLE IF NOT EXISTS `news_gif` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titre` varchar(100) NOT NULL,
  `timestamp` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
 
INSERT INTO `news_gif` (`id`, `titre`, `timestamp`) VALUES
(1, 'Ouverture du site', 1171298713),
(2, 'Ouverture forum', 1172191293),
(3, 'Test fil rss', 1203603483);


Pour l'effet "machine à écrire", vous aurez besoin de la fonction str_split(VOTRE_CHAINE). Si vous n'avez pas php5, vous pouvez la remplacer par : preg_split('//', VOTRE_CHAINE, -1, PREG_SPLIT_NO_EMPTY).

N'oubliez pas d'indiquer la date de la dernière modification.

Mettez votre code dans une fonction car, à chaque ajout / modification / suppression de news, il faudra remettre l'image à jour, et ça serait bête de réécrire 3 fois le même code. :p

Je vous ai tout dit : à vous de jouer.

Correction :

Secret (cliquez pour afficher)

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
function creer_fil_rss()
{
        require('libs/connexion.php'); //Fichier gérant la connexion à ma bdd
        require('libs/gif.class.php');
        
        $retour = mysql_query('SELECT titre, timestamp FROM news_gif ORDER BY id DESC LIMIT 0, 1') or die(mysql_error()); //Sélectionne le dernier article
        $donnees = mysql_fetch_array($retour);

	/* La chaine correspondra au dernier titre du blog
	 * L'espace blanc crée une image vide afin de rendre l'animation plus fluide (essayez de l'enlever)
	 */

        $chaine = ' '.$donnees['titre'];
        $taille_chaine = strlen($chaine);
        $chaine = str_split($chaine); //Transforme la chaîne en tableau
        
        $animation = array();
        $duree = array();
        
        $largeur = 220;
        $hauteur = 60;
        $image = imagecreatefromjpeg('fond_rss.jpg'); //Notre joli fond :p
        
        $fond = imagecolorallocate($image, 249, 249, 249);
        $bleu = imagecolorallocate($image, 0, 0, 255);
        $noir = imagecolorallocate($image, 9, 9, 9);
        $vert = imagecolorallocate($image, 146, 201, 146);
        
        imagestring($image, 5, 65, 5, "Bob's home", $bleu); //Un petit titre
        imagestring($image, 3, 9, 40, 'Le '.date('d/m/Y \a H\hi', $donnees['timestamp']), $vert); //Affiche la date de la dernière modification sur l'article
        
        foreach($chaine as $i => $carac) //Pour chaque lettre de la chaîne, on crée une nouvelle image
        {
                $txt .= $carac; //On affiche jusqu'au caractère actuel
                imagestring($image, 4, 9, 23, $txt, $noir);
        
                ob_start(); //Je ne vous explique pas : vous devriez avoir compris ^^
                imagegif($image);
                $animation[] = ob_get_clean();
        
                if($i == 0)
			$duree[] = 45;
		else if($i+1 == $taille_chaine) //Si on est à la fin de la chaîne, on marque une pause
                        $duree[] = 200;
                else
                        $duree[] = 15;
        }
        imagedestroy($image); //On détruit l'image pour libérer de la mémoire
        
        $gif = new GIFEncoder($animation, $duree, 0, 2, 0, 0, 0, "bin"); //On génère l'animation
        $fichier = fopen('VOTRE_IMAGE.gif', 'w+');
        fputs($fichier, $gif->GetAnimation()); //On enregistre
        fclose($fichier);
}
?>



Et voilà : notre fonction est terminée ; vous pouvez vérifier qu'elle effectue bien son travail en éditant votre table. ;)

Exercices supplémentaires (par ordre de difficulté croissante)



Q.C.M.

La librairie GD ne permet pas de :
Qu'est-ce qu'une animation ?
Que fait ce code ?
Code : PHP
1
2
3
4
<?php
$gif = new GIFEncoder($animation, $duree, 0, 2, 0, 0, 0, "bin");
echo $gif->GetAnimation();
?>

Test ultime : combien y a-t-il d'erreurs dans ce script ?

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
require('libs/connexion.php'); //On se connecte à notre BDD
require('libs/gif.class.php');
 
$retour = mysql_query('SELECT titre, timestamp FROM news_gif ORDER BY id DESC LIMIT 0, 1'); //Sélectionne le dernier article
$donnees = mysql_fetch_array($retour);
$chaine = $donnees['titre']; //La chaîne correspondra au dernier titre du blog
$taille_chaine = strlen($chaine);
str_split($chaine); //Transforme la chaîne en tableau
 
$animation = array();
$duree = array();
 
$largeur = 220;
$hauteur = 60;
$image = imagecreatefromjpeg('fond_rss.jpg'); //Notre joli fond :p
 
$fond = imagecolorallocate($image, 249, 249, 249);
$bleu = imagecolorallocate($image, 0, 0, 255);
$noir = imagecolorallocate($image, 9, 9, 9);
$vert = imagecolorallocate($image, 146, 201, 146);
 
imagestring($image, 5, 65, 5, "Bob's home", $bleu); //Un petit titre
imagestring($image, 3, 9, 40, 'Le '.date('d/m/Y \a H\hi', $donnees['timestamp']), $vert); //Affiche la date de la dernière modification sur l'article
 
foreach($chaine as $carac) //Pour chaque lettre de la chaîne, on crée une nouvelle image
{
        $txt = $carac; //On affiche jusqu'au caractère actuel
        imagestring($image, 4, 9, 23, $txt, $noir);
 
        ob_start(); //Je ne vous explique pas : vous devriez avoir compris ^^
        imagegif($image);
        $animation = ob_get_clean();
 
        if($i+1 == $taille_chaine) //Si on est à la fin de la chaîne, on marque une pause
                $duree[] = 200;
        else
                $duree[] = 15;
}
imagedestroy($image); //On détruit l'image pour libérer de la mémoire
 
$gif = new GIFEncoder($duree, $animation, 0, 2, 0, 0, 0, "bin"); //On génère l'animation
$fichier = fopen('image.gif', 'w');
fputs($fichier, $gif->GetAnimation()); //On enregistre
fclose($fichier);
?>


Vous voici arrivé à la fin de ce tutoriel : vous êtes désormais capables de créer de beaux gif animés. Attention ! Restez dans la sobriété : c'est toujours très désagréable d'assister à un feu d'artifice sur une page web. ^^

Pour toute suggestion ou critique, merci de me contacter par MP.
Auteur : Phoenix76
Noter et commenter ce tutoriel
Imprimer ce tutoriel

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 428 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1173s (0.1045s)