Vous pouvez voir un autre exemple de page créée par CGI avec du graphisme
J'ai donc inséré une image, en donnant l'adresse absolue du programme exécutable "compteur" (attention, le chemin des CGI, ici cgi-bin, est un chemin "calculé" par le serveur, il correspond à un chemin d'habitude différent de celui des fichiers HTML normaux, c'est pour cela que j'ai mis l'adresse absolue et non relative).
J'ai ensuite donné les arguments transmis à ce programme (par ?nom1=val1&nom2=val2&nom3=val3...), ici une seule seule variable (nom), avec une valeur définissant le nom de ma page (pas nécessairement le nom du fichier).
J'ai de plus centré l'image verticalement dans la ligne (align=middle).
Dans ce programme, la fonction int cgiMain()est la fonction principale (la vraie fonction main est dans la librairie cgic).
Dans cette fonction, j'envoie l'entête du document (le code qui permet à mon navigateur de savoir le type de document qu'il recoit, ici une image GIF) par l'instruction :
Puis je recherche dans un fichier local le nombre précédent d'appels avec ce même nom par la fonction :
Puis je "dessine" ce nombre sous forme d'un GIF par la fonction :
Et Voilà !
#include <stdio.h> /* les 3 bibliothèques ci-dessous sont récupérées sous "http://www.boutell.com" */ /* que Mr Boutell en soit chaleureusement remercié */ #include "cgic.h" /* pour faire du cgi en C */ #include "gd.h" /* pour créer un GIF en C */ #include "gdfontl.h" /* pour écrire en "large" */ #define nomfic "compteur.dat" #define nbmax 1000 /* cette limite n'est là que pour empêcher des bouclages infinis */ typedef char tnom[80]; typedef struct { tnom nom; int nb; }info; int incrementeinfo(info *x) /* retourne l'index du nom dans le fichier (-1 si erreur), et met dans le champ x->nb la valeur trouvée dans le fic. S'il n'existe pas encore, il le créée (avec nb=0) */ { FILE *fic; size_t err; info actu; int index; if((fic=fopen(nomfic,"r+"))==NULL) /* ouverture en lecture+écriture, le fichier doit exister, même vide */ {perror("ERREUR OUVERTURE");return(-1);} for(index=0;index<nbmax;index++) { err=fread(&actu,sizeof(info),1,fic); /* lecture d'une info dans le fichier */ /* printf("LECTURE DE %s (NB=%d) ERR=%ld\n",actu.nom,actu.nb,err); */ if (err>0L) { if(!strncmp(actu.nom,x->nom,nbmax)) /*ils sont egaux*/ { x->nb=actu.nb+1; fclose(fic); return(index); } /* sinon tester le suivant */ } else if(!err) /* || eof(fic) normalement le deuxieme test est inutile */ { /* on est à la fin du fichier: il on le rajoute */ x->nb=0; if(fwrite(x,sizeof(info),1,fic)<=0) /* si negatif plus de place sur le disque */ {printf("erreur d'ecriture sur fic !!!");return(-1);} fclose(fic); return(index); } } printf("attention, on a depasse %d enregistrements\n",nbmax); return(-1); } int creeimage(int i) /* crée une image GIF dans laquelle on met la valeur de i */ { char texte[7]; /* la var string qui contiendra le nb i */ /* Declare l'image */ gdImagePtr im; /* Declare an output file , ici inutile car je ne stocke pas le résultat sur fichier */ /* FILE *out; */ /* Declare color indexes */ int c_fond; int c_text; int c_cadr; sprintf(texte,"%06d",i); /* traduction de i en chaîne ASCII */ /* Allocate the image: 80 pixels across by 30 pixels tall */ im = gdImageCreate(80, 30); /* Allocate the color black (red, green and blue all minimum). Since this is the first color in a new image, it will be the background color. */ c_fond = gdImageColorAllocate(im, 0, 0, 0); /* Allocate the color white (red, green and blue all maximum). */ c_text = gdImageColorAllocate(im, 255, 255, 255); /* cadre presque rouge */ c_cadr = gdImageColorAllocate(im, 255, 25, 25); /* dessin d'un cadre. j'utilise gdImageSX qui me donne la taille en X de l'image (ici 80), idem en Y */ gdImageRectangle(im, 2, 2, gdImageSX(im)-3, gdImageSY(im)-3, c_cadr); gdImageString(im, gdFontLarge, gdImageSX(im) / 2 - (strlen(texte) * gdFontLarge->w / 2), /* débuter au milieu de l'image moins la taille de la moitié des caractères à afficher */ gdImageSY(im) / 2 - gdFontLarge->h / 2, texte, c_text); /* écrire le texte AU MILIEU !!!! */ /* ouvrir le fic résultat, inutile ici car sortie directe */ /* out = fopen("compteur.gif", "w+");*/ /* Output the image to the disk file. */ gdImageGif(im, cgiOut); /* ou uniquement out */ /* Close the file. */ /* fclose(out);*/ /* Destroy the image in memory. */ gdImageDestroy(im); return(0); } int cgiMain() /* le main pour Cgic, le "vrai" main étant dans cgic.h */ { info i; /* Important: we must indicate the type of document */ cgiHeaderContentType("image/gif");/* "text/html" habituellement */ /* récupérer la valeur de la variable "nom" envoyée par le demandeur */ cgiFormStringNoNewlines("nom",i.nom,sizeof(tnom)); /* rechercher le nb d'accès précédents et incrémentation */ incrementeinfo(&i); /* "dessiner" ce nombre sous forme d'un GIF */ creeimage(i.nb); /*printf("il y etait %d fois (IL Y EST UNE FOIS DE PLUS)\n\n",i.nb);*/ }
#----makefile pour compteur.c ---------- P.TRAU (testé sous Solaris 2.3) #mon compilateur est gcc, modifiez la ligne si vous en avez un autre CC=gcc AR=ar CFLAGS=-O LIBS=-L./ -lgd -lcgic -lm all: libgd.a libcgic.a compteur compteur: compteur.o libgd.a gd.h gdfonts.h gdfontl.h $(CC) compteur.o -o compteur $(LIBS) libgd.a: gd.o gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \ gd.h gdfontt.h gdfonts.h gdfontmb.h gdfontl.h gdfontg.h rm -f libgd.a $(AR) rc libgd.a gd.o gdfontt.o gdfonts.o gdfontmb.o \ gdfontl.o gdfontg.o libcgic.a: cgic.o cgic.h rm -f libcgic.a $(AR) rc libcgic.a cgic.o clean: rm -f *.o *.a compteur