Voici le deuxième article concernant gd. Il traite de l'utilisation de Freetype pour inclure du texte dans vos images et des nouveautés apportées à gd par la version 2.
Téléchargez la dernière version de Freetype-2. Lors de l'criture de l'article, il s'agissait de la version 2.0.3.
Voici comment on l'installe...
Placez vous dans le répertoire dans lequel vous avez téléchargé freetype puis tapez :
tar xvfy freetype-2.0.3.tar.bz2 cd freetype-2.0.3 make setup make su make installCela installe freetype sous /usr/local. Vous pouvez ensuite redevenir "simple utilisateur".
Pour avoir plus d'info sur l'installation de gd, consultez le premier article sur gd, sur léa.
Placez vous dans le répertoire dans lequel vous avez téléchargé gd puis tapez
tar xvfz gd-2.0.1.tar.gz cd gd-2.0.1Editez le début du Makefile comme suit :
COMPILER=gcc AR=ar CFLAGS=-g -DHAVE_LIBPNG -DHAVE_LIBJPEG -DHAVE_LIBFREETYPE LIBS=-lgd -lpng -lz -ljpeg -lfreetype -lm INCLUDEDIRS=-I. -I/usr/local/include/freetype2 LIBDIRS= INSTALL_LIB=/usr/local/lib INSTALL_INCLUDE=/usr/local/include INSTALL_BIN=/usr/local/binPuis tapez:
su make installIl ne s'agit pas d'une erreur de ma part, il faut bien taper directement
make install
, c'est comme ça !gdImageCreateFromPng
par exemple) :
/usr/local/include/freetype2
dans la ligne INCLUDEDIRS
du Makefile.Pour les notions de base concernant gd, reportez vous à l'article précédent, celui-ci constitue une suite.
Dans cet exemple nous allons recréer l'image simple du premier exercice du premier article mais ajouterons
dans la croix la mention santé écrite en Comics, par exemple, et ce, en jaune.
Il faut :
mkdir /usr/share/ttf
cp /mnt/NTC/winnt/Fonts/comic.ttf /usr/share/ttf/
char *gdImageStringFT(gdImagePtr im, int *brect, int color, char *fontname, double ptsize, double angle, int x, int y, char *chaine)où :
/* * Fichier expl_gd2_1.c * * Pour les explications de base, * se reporter à l'article sur gd. */ #include <stdlib.h> #include <gd.h> // Deux macros qui simplifient la vie #define brect_largeur (brect[4]-brect[0]) #define brect_hauteur (brect[1]-brect[5]) int main(void) { gdImagePtr image; FILE *image_png; char *err; int rouge, blanc, jaune, noir; char *chaine = "santé"; // La chaîne à écrire char *font = "/usr/share/ttf/comic.ttf"; // La police double taille = 20; // La taille de la police int brect[8]; // Les coordonnées du rectangle entourant le texte entier. /* brect[0] X bas gauche * brect[1] Y bas gauche * brect[2] X bas droit * brect[3] Y bas droit * brect[4] X haut droit * brect[5] Y haut droit * brect[6] X haut gauche * brect[7] Y haut gauche */ image = gdImageCreate(100, 100); blanc = gdImageColorAllocate(image, 255, 255, 255); rouge = gdImageColorAllocate(image, 255, 0, 0); jaune = gdImageColorAllocate(image, 255, 255, 0); noir = gdImageColorAllocate(image, 0, 0, 0); gdImageFilledRectangle(image, 20, 40, 80, 60, rouge); gdImageFilledRectangle(image, 40, 20, 60, 80, rouge); /* Les nouveautés commencent ici */ /* On a droit à 60x20 pour placer notre chaîne * soit brect[4]-brect[0]<60 ET brect[1]-brect[5]<20 * --> Pour récupérer brect sans écrire le texte, on place im à NULL * Si on a un dépassement on réduit la taille de la police et on recommence */ do { err = gdImageStringFT (NULL, brect, jaune, font, taille--, 0, 0, 0, chaine); if (err) fprintf(stderr, "%s\n", err); fprintf (stderr, "Essai taille : %.0f\n", taille+1); fprintf (stderr, "* bas gauche ( %d, %d ), haut droite ( %d, %d )\n", brect[0], brect[1], brect[4], brect[5]); fprintf (stderr, "* largeur x hauteur : %dx%d\n", brect_largeur, brect_hauteur); } while ( ( brect_hauteur >= 20 ) || ( brect_largeur >= 60 ) ); /* A décommenter pour voir le brect gdImageRectangle (image, 50-brect_largeur/2, 50-brect_hauteur/2, 50+brect_largeur/2, 50+brect_hauteur/2, noir); */ /* Une fois ici on a la bonne taille moins un. * Le milieu de l'image la moitié de la largeur nous donne le x gauche. * Le milieu de l'image + la moitié de la hauteur nous donne le y bas. * On retracnche la moitié des brect[0] et brect[1] * car on a vu qu'il ne valaient pas nécessairement 0 d'où un décalage */ err = gdImageStringFT (image, brect, // mettre -jaune pour supprimer l'anti-aliasing jaune, font, ++taille, 0, 50-(brect_largeur-brect[0])/2, 50+(brect_hauteur-brect[1])/2, chaine); if (err) fprintf(stderr, "%s\n", err); /* Les nouveautés s'arrêtent ici */ image_png = fopen("expl1.png", "w"); gdImagePng(image, image_png); fclose(image_png); gdImageDestroy(image); exit (0); }On compile en tapant
gcc -o expl_gd2_1 expl_gd2_1.c -lgd -ljpeg -lpng -lfreetype
./expl_gd2_1
, vous obtenez dans le répertoire courant une image expl1.png, qui sera une des 4 présentées
ci-dessous selon les modifications que vous aurez apporté au code :
Image normale | Sans anti-aliasing (-jaune) | Avec dessin du brect | Avec brect / Sans anti-aliasing |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Remarque : Dans une application réelle, une fois connue la bonne taille de police, vous enleveriez la boucle
permettant de la trouver, vous ne traceriez pas le brect, etc ... Je l'ai fait ici dans un but pédagogique.
Nous allons maintenant écrire, selon un angle. Pas de gros changements ... On en profitera toutefois au passage pour faire connaissance
avec le type gdPoint, utilisé pour tracer des polygones de façon aisée. Il nous servira pour tracer le brect de ce texte
"en pente", grâce à la fonction gdImagePolygon.
On note qu'un type gdPoint a deux champs, x et y. C'est pas plus compliqué que ça !
Le code :
/* * Fichier expl_gd2_2.c * * Pour les explications de base, * se reporter à l'article sur gd. */ #include <stdlib.h> #include <stdio.h> #include <gd.h> #include <math.h> // Une macro pour transformer des degrés en radians // NB: M_PI est définie dans math.h #define en_radians(ndeg) (M_PI*(ndeg)/180) // Deux macros qui simplifient la vie #define brect_largeur (brect[4]-brect[0]) #define brect_hauteur (brect[1]-brect[5]) int main(void) { gdImagePtr image; FILE *image_png; char *err; int rouge, blanc, jaune, noir; char *chaine = "santé"; // La chaîne à écrire char *font = "/home/xavier/Docs/contribs_lea/c4/comic.ttf"; double taille = 20; // La taille de la police int brect[8]; // Les coordonnées du rectangle entourant le texte entier. gdPoint brect_points[4]; // Le tableau de points pour tracer le polygone image = gdImageCreate(100, 100); blanc = gdImageColorAllocate(image, 255, 255, 255); rouge = gdImageColorAllocate(image, 255, 0, 0); jaune = gdImageColorAllocate(image, 255, 255, 0); noir = gdImageColorAllocate(image, 0, 0, 0); gdImageFilledRectangle(image, 20, 40, 80, 60, rouge); gdImageFilledRectangle(image, 40, 20, 60, 80, rouge); err = gdImageStringFT (NULL, brect, jaune, font, taille, en_radians(45), 0, 0, chaine); /* on stocke les points dans le tableau de gdPoints */ brect_points[0].x = brect[0]+50-(brect_largeur-brect[0])/2; brect_points[0].y = brect[1]+50+(brect_hauteur-brect[1])/2; brect_points[1].x = brect[2]+50-(brect_largeur-brect[0])/2; brect_points[1].y = brect[3]+50+(brect_hauteur-brect[1])/2; brect_points[2].x = brect[4]+50-(brect_largeur-brect[0])/2; brect_points[2].y = brect[5]+50+(brect_hauteur-brect[1])/2; brect_points[3].x = brect[6]+50-(brect_largeur-brect[0])/2; brect_points[3].y = brect[7]+50+(brect_hauteur-brect[1])/2; /* On trace le polygone */ gdImagePolygon (image, brect_points, 4, noir); /* On ajoute la chaîne de caractères comme avant, mais avec un angle */ err = gdImageStringFT (image, brect, jaune, font, taille, en_radians(45), 50-(brect_largeur-brect[0])/2, 50+(brect_hauteur-brect[1])/2, chaine); if (err) fprintf(stderr, "%s\n", err); image_png = fopen("expl2.png", "w"); gdImagePng(image, image_png); fclose(image_png); gdImageDestroy(image); exit (0); }On compile en tapant
gcc -o expl_gd2_2 expl_gd2_2.c -lgd -ljpeg -lpng -lfreetype
./expl_gd2_2
, vous obtenez dans le répertoire courant une image expl2.png.
Ben oui !!! Vous devez bien vous le demander ! Alors voici ce que dit (en résumé) la section "what's new ?" de la page officielle pour la version 2.0.1 par rapport à la 1.8.3 du précédent article :
DEFAULT_FONTPATH
et GDFONTPATH
. (1.8.4)/* * Fichier expl_gd2_3.c * * Pour les explications de base, * se reporter à l'article sur gd. */ #include <stdlib.h> #include <gd.h> int main(void) { FILE *image_png; gdImagePtr image, image_d_avant; int orange, bleu; // On crée une image TrueColor image = gdImageCreateTrueColor(100, 100); // On alloue une couleur orange = gdTrueColor (255, 128, 0); // On trace un rectangleorange gdImageFilledRectangle(image, 0, 0, 100, 100, orange); // On ouvre l'image du premier exercice et on en crée une image image_png = fopen("expl1.png", "r"); image_d_avant = gdImageCreateFromPng (image_png); fclose (image_png); // on copie avec remise à l'échelle de 100x100 pixels en partant de (0,0) de l'ancienne image // on place le résultat de taille 90x90 à (5,5) dans la nouvelle gdImageCopyResampled(image, image_d_avant, 5, 5, 0, 0, 90, 90, 100, 100); // on détruit l'ancienne image en mémoire. gdImageDestroy (image_d_avant); // On alloue une couleur bleue semi transparente bleu = gdTrueColorAlpha(0, 0, 255, gdAlphaTransparent / 2); // on se met en mode écrasement // La où on dessinera il y aura du bleu semi-transparent, c'est tout gdImageAlphaBlending(image, 0); // ontrca eun rectangle gdImageFilledRectangle(image, 10, 10, 90, 30, bleu); // On se met en mode "mélange" // Ce qu'on dessine, se mélange avec ce qu'il y a dessous // 50% de bleu et 50% du dessous gdImageAlphaBlending(image, 1); gdImageFilledRectangle(image, 40, 10, 90, 90, bleu); image_png = fopen("expl3.png", "w"); gdImagePng(image, image_png); fclose(image_png); gdImageDestroy(image); exit (0); }On compile en tapant
gcc -o expl_gd2_3 expl_gd2_3.c -lgd -ljpeg -lpng -lfreetype
C'est tout pour cette fois !
N'hésitez pas à envoyer vos commentaires par mail en cliquant sur mon nom en haut de la page.
Retrouvez prochainement l'article remis en forme, les sources, archives et binaires sur mon site perso...,
http://www.xgarreau.org/.
a+