17 février 2020
GD est une librairie graphique écrite en C qui permet de créer ou ouvrir des images (jpg, png, gif, etc.) et de tracer dedans des formes géométriques (ligne, rectangle, cercle, etc.). Elle permet aussi quelques manipulations élémentaires. Le langage est C.
Code provenant du site officiel, dont le résultat est l'image ci-contre.
/*gd-ex1.cgcc gd-ex1.c -o gd-ex1 -lgd*/#include "gd.h"#include <stdio.h>int main() {gdImagePtr im; // déclare l'imageFILE *jpegout; // déclare le fichier de sortieint black; // index des couleursint white;// Alloue une image 128×128 pixelsim = gdImageCreate(128, 128);// Allocation des couleurs RGBblack = gdImageColorAllocate(im, 0, 0, 0); // fondwhite = gdImageColorAllocate(im, 255, 255, 255); // couleur de tracé// Dessine une ligne entre le coin supérieur gauche et le coin opposégdImageLine(im, 0, 0, 127, 127, white);// ouvre le fichier en écriturejpegout = fopen("gd-ex1.jpg", "w");// écrit l'image sur le disque avec les réglages par défaut -1gdImageJpeg(im, jpegout, -1);// ferme le fichier et libère la mémoire de l'imagefclose(jpegout);gdImageDestroy;}
C'est remarquablement simple et efficace.
Remarques :
gcc gd-ex1.c -o gd-ex1 -lgd
Il est inspiré du Linux journal et permet de travailler sur une image existante. Dans cet exemple nous rajouterons une barre au pingouin en utilisant ligne et rectangle.
/* gd-eg2.c */#include <gd.h>#include <stdio.h>int main(){gdImagePtr tux;FILE *out, *in;int black, grey, white;in = fopen("tuxin.jpg","r");tux = gdImageCreateFromJpeg(in);fclose(in);// couleursblack = gdImageColorAllocate(tux, 0, 0, 9);grey = gdImageColorAllocate(tux, 160, 160, 200);white = gdImageColorAllocate(tux, 200, 200, 200);// ligne et rectanglesgdImageLine(tux, 12, 50, 88, 50, white);gdImageFilledRectangle(tux, 11, 51, 89, 52, grey);gdImageFilledRectangle(tux, 11, 53, 89, 60, black);out = fopen("tuxout.jpg", "w");gdImageJpeg(tux, out, -1);fclose(out);gdImageDestroy(tux);}
Reamrque
Il y avait des erreurs dans l'article du Linux Journal que je n'ai pas su élucider.
J'ai fait des tas de programmes pour tracer le graphe d'une courbe. En général c'est pour illustrer les articles de ce site. Mais celui qui me plait le plus c'est celui présenté ci-dessous. Il me plait parce que je dessine directement dans l'image en création. Plus j'utilise GD, plus je le trouve génial. Il y a tout ce qu'il faut, et tout y est extêmement simple.
Code source de gd-plot.c
/* gd-plot.c:w | !gcc % -o %< -lgd && ./%< && display gd-plot.jpg*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <gd.h>#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))gdImagePtr im; // image pointerFILE *jpeg;int bg, fg; // background and foreground colorsconst int pad = 8; // paddingfloat xO = 1.5, yO = 1.5; // originint sx = 25, sy = 25; // scalesint W = 100 + 2*pad, H = 125 + 2*pad; // image width, height// debugfloat _x = 0, _y = 0; // last position// x, y to screen X, Y coordinatesint X(float x) {return round(x*sx + xO*sx) + pad; }int Y(float y) {return H - round(y*sy + yO*sy) -pad;}// convenience drawingsvoid line(float, float, float, float);void lineto(float x, float y) {line(_x, _y, x, y);}void str(char *, float, float);void axis();void plot(float, float); // plottingfloat f(float x) {return x*x - 1;} // example function to plotint main(int argc, char *argv[]){im = gdImageCreate(W, H);bg = gdImageColorAllocate(im, 255, 255, 255);fg = gdImageColorAllocate(im, 0, 0, 0);axis();plot(-1, 2);str("x ∈ [-1, 2] ↦ x² - 1", 5, 10);jpeg = fopen("gd-plot.jpg", "w");gdImageJpeg(im, jpeg, -1);fclose(jpeg);gdImageDestroy(im);}void line(float x1, float y1, float x2, float y2) {gdImageLine(im, X(x1), Y(y1), X(x2), Y(y2), fg);_x = x2; _y = y2;}void str(char *s, float x, float y){int brect[8];char *font= "/usr/share/fonts/TTF/DejaVuSans.ttf";gdImageStringFT(im, brect, fg, font, 8, 0, x, y, s);}void axis(){float d = 0.05; // unitsline(-xO, 0, (W - 2*pad)/sx -xO, 0);line(1, d, 1, -d);line(0, -yO, 0, (H - 2*pad)/sy- yO);line(-d, 1, d, 1);str("O", X(-0.4), Y(-0.4));str("1", X(1.02), Y(-0.4));str("1", X(-0.4), Y(1.02));}void plot(float a, float b){gdImageSetThickness(im, 2); // thicknessfloat xi = 0.05; // stepline(a, f(a), a + xi, f(a + xi)); // starting linefor(float x=a+2*xi; x<b; x+=xi) lineto(x, f(x));gdImageSetThickness(im, 1); // reset thickness}
Résultat ci-contre : 
Ligne 34 : Création d'une image
C'est la fonction gdImageCreate qui alloue le pointeur im et crée l'image avec la couleur de fond fg qui est la première couleur allouée dans le programme. ligne 35.
Voir gdImageCreate et couleur de fond dans les commentaires du code donné en exemple : /* Allocate the color ....
Ligne 42 : Enregistrement de l'image
gdImageJpeg enregistre l'image pointée par im au format JPEG. Voir gdImageJpeg et Image formats dans la side bar du site.
D'autres formats sont possibles.
Ligne 47 : Fonction line
On utilise la fonction gdImageLine.
La fonction gdImageThickness permet de définir l'épaisseur du trait. Par exemple après l'appel de gdImageThickness(im, 3) tous les tracés dans l'image pointée par im auront une épaisseur de 3 pixels. Pour changer cette propriété il faut l'appeler à nouveau.
La fonction lineto (Ligne 25) est une commodité qui permet d'enchaîner les tracés en fournissant les coordonnées du point suivant.
Voir gdImageLine et la rubrique other de gd.c, Summary.
Ligne 52 : Fonction str
C'est une fonction de tracé de texte. On y utilise la fonction gdImageStringFT. Voir les fonctions de la rubrique FreeType font rendering.
Ligne 71 : Fonction plot
On fixe l'épaisseur du trait à 3, on trace la courbe, puis on remet l'épaisseur du trait à 1. Sait-on jamais.
Remarque : La ligne 2 fera l'objet d'un article Vim.
Cette bibliothèque est géniale. Elle fourmille de potentialités. Je regrette de ne l'avoir pas découverte plus tôt. Par exemple pour faire une image d'illustration, une courbe ou une représentation graphique, elle constitue l'outil idéal. Car pour nous qui programmons, nous n'avons pas besoin d'usine à gaz qui s'adapte à tout sauf à ce qu'on a prévu de faire.