Bonjour à tous,
J'ai un tableau où chaque élément correspond à l'intensité d'un pixel. Je souhaiterai afficher dans une fenêtre l'image associée mais je ne sais pas comment faire ceci. Pouvez vous m'aidez s'il vous plaît ?
Bonjour à tous,
J'ai un tableau où chaque élément correspond à l'intensité d'un pixel. Je souhaiterai afficher dans une fenêtre l'image associée mais je ne sais pas comment faire ceci. Pouvez vous m'aidez s'il vous plaît ?
Pour répondre simplement il te faut passer par une bibliothèque capable de gérer l'environnement graphique que tu utilises. Pour ma part c'est Gtk+. Mais il y en a d'autres...
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
J'utilise la SDL mais après je ne sais pas comment procéder pour m'afficher l'image.
J'imagine qu'il faut passer par ces fonctions :
http://wiki.libsdl.org/moin.cgi/CategoryPixels
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
J'ai trouvé plutôt cette fonction qui me semble plus adaptée à ce que tu recherches :
SDL_ConvertPixels();.
Utilisation de Glade avec Gtk+
Code::Blocks et Gtk+ sous Windows
Programmation orientée objet avec Gtk+ v3
- N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk
Bonsoir,
Avec la SDL le plus simple serait de créer une SDL_Surface avec tes pixels afin de l'afficher.
Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
Un peu de programmation réseau ?
Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.
j'ai trouvé une solution, la voici :
Cependant j'ai un souci avec le redimensionnement de l'image.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
57
58
59 void affiche(double **I,int nrow,int ncol) { int i,j,k=0; // ######## affichage de l'image a l'ecran ########################## SDL_Surface *ecran = NULL, *lignes[nrow*ncol]={NULL}; SDL_Rect position; SDL_Init(SDL_INIT_VIDEO); ecran = SDL_SetVideoMode(nrow,ncol, 32, SDL_HWSURFACE|SDL_RESIZABLE); for (i = 0 ; i <nrow*ncol; ++i) lignes[i] = SDL_CreateRGBSurface(SDL_HWSURFACE,1,1, 32, 0, 0, 0, 0); SDL_WM_SetCaption("Picture SDL", NULL); SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); // la couleur de l'ecran est noir for (i = 0 ; i < nrow; ++i){ for(j=0;j<ncol;++j,++k){ position.x = j; // Les lignes sont à gauche (abscisse de 0) position.y = i; // La position verticale dépend du numéro de la ligne SDL_FillRect(lignes[k], NULL, SDL_MapRGB(ecran->format, I[i][j],I[i][j],I[i][j])); SDL_BlitSurface(lignes[k], NULL, ecran, &position); }} SDL_Flip(ecran); pause(); for (i = 0 ; i <nrow*ncol; ++i) // N'oubliez pas de libérer les 199*199 surfaces SDL_FreeSurface(lignes[i]); SDL_Quit(); return; } void pause() { int continuer = 1; SDL_Event event; while (continuer) { SDL_WaitEvent(&event); switch(event.type) { case SDL_QUIT: continuer = 0; } } }
Pouvez vous m'aider ?
Bonsoir,
Pour moi, tu peux déjà simplifier ta fonction, en te passant de la variable lignes:
Ensuite, quel est ton problème de redimensionnement? Et comment se présente le paramètre I que tu passes à la fonction?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 void affiche(double **I,int nrow,int ncol) { int i,j; //,k=0; // ######## affichage de l'image a l'ecran ########################## SDL_Surface *ecran = NULL; //, *lignes[nrow*ncol]={NULL}; SDL_Rect position; SDL_Init(SDL_INIT_VIDEO); ecran = SDL_SetVideoMode(nrow,ncol, 32, SDL_HWSURFACE|SDL_RESIZABLE); // for (i = 0 ; i <nrow*ncol; ++i) // lignes[i] = SDL_CreateRGBSurface(SDL_HWSURFACE,1,1, 32, 0, 0, 0, 0); SDL_WM_SetCaption("Picture SDL", NULL); SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); // la couleur de l'ecran est noir position.w=position.h=1; for (i = 0 ; i < nrow; ++i){ for(j=0;j<ncol;++j) { // ,++k){ position.y = i; // La position verticale dépend du numéro de la ligne position.x = j; // Les lignes sont à gauche (abscisse de 0) // SDL_FillRect(lignes[k], NULL, SDL_MapRGB(ecran->format, I[i][j],I[i][j],I[i][j])); // SDL_BlitSurface(lignes[k], NULL, ecran, &position); SDL_FillRect(ecran,&position,SDL_MapRGB(ecran->format, I[i][j],I[i][j],I[i][j])); }} SDL_Flip(ecran); pause(); // for (i = 0 ; i <nrow*ncol; ++i) // N'oubliez pas de libérer les 199*199 surfaces // SDL_FreeSurface(lignes[i]); SDL_Quit(); return; }
On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent
Ok ça marche aussi,
En fait mon paramètre I est une matrice de double qui contient les valeurs des pixels en niveau de gris d'une image.
Le souci de redimensionnement c'est que lorsque j'affiche mon image de taille 199*199, je souhaiterai agrandir la fenêtre.
La fenêtre change bien de dimension mais l'image reste à la même taille.
Je souhaiterai que l'image se redimensionne avec la fenêtre.
Par contre j'ai pas compris cette instruction :
position.w=position.h=1;
Pouvez vous me l'expliquer ?
Sans être présomptueux, le contraire m'eut étonnéOk ça marche aussi
SDL_FillRect remplit une portion de surface (ecran en l'occurence) avec un rectangle. Ce rectangle est défini par position.x et position.y pour les coordonnées du coin supérieur gauche, et par position.w et position.h pour ce qui est des largeur et hauteur du rectangle. Comme tu ne remplis qu'un pixel, w=h=1.Par contre j'ai pas compris cette instruction :
position.w=position.h=1;
Pouvez vous me l'expliquer ?
Si, par exemple, w=10 et h=35, une surface de 10 pixels de largeur et de 35 pixels de hauteur serait remplie avec la couleur demandée.
Pour ce qui est du redimensionnement, c'est un peu plus délicat*. Il faut d'abord, via un event, repérer le fait que l'utilisateur change la taille de la fenêtre. Ensuite, il faut récupérer la nouvelle taille (plus grande ou plus petite), et appliquer une fonction de redimensionnement à l'image, qui s'appelle rotozoomSurface(...). Cette fonction n'est pas disponible en standard avec SDL, mais bien dans un set de fonctions qui s'appelle SDL_gfx, que tu peux télécharger ici (voir le click here dans la page )Le souci de redimensionnement c'est que lorsque j'affiche mon image de taille 199*199, je souhaiterai agrandir la fenêtre.
Je souhaiterai que l'image se redimensionne avec la fenêtre.
Si tu as besoin de plus d'explications, n'hésite pas.
Edgar.
* cela changera la physionomie de ton programme. Mais bon, rien de bien compliqué, uniquement quelques aménagements.
On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent
Bonjour,
Avec les informations que nous avons actuellement, la bibliothèque des bibliothèques plus évolués que la SDL aurait été préférable. Je pense à Qt ou GTK ou autre du même genre. Je dis cela, car tout ce que l'on a vu jusqu'à maintenant, ne justifie toujours pas le choix de la SDL. Sauf si vous voulez refaire quelques routines bas niveau, mais cela pas du tout le cas.
Sinon, bonne continuation.
Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi
Ma page sur DVP
Mon Portfolio
Qui connaît l'erreur, connaît la solution.
Bonjour à tous,
Je me permet de ré-ouvrir ce topic car j'ai un problème d'affichage avec certaines images en utilisant la méthode que vous m'avez préconisé.
J'arrive à afficher des images de faibles résolutions mais quand il s'agit d'images de plus grandes tailles chez moi ça ne fonctionne pas.
La taille de l'image testée est de 1920 X 2560, pouvez-vous m'aidez svp ?
C'est un peu vague. Qu'et-ce qui ne fonctionne pas?chez moi ça ne fonctionne pas
Je viens de tester ceci
qui fonctionne très bien. Evidemment, la fenêtre ouverte est nettement plus grande que la surface de l'écran.
Code : Sélectionner tout - Visualiser dans une fenêtre à part ecran = SDL_SetVideoMode(1920,2560, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent
En fait la fenêtre s'affiche, cependant l'image ne s'affiche pas dans la fenêtre.
Ce qui est bizarre avec des résolutions plus faible l'image s'affiche.
Je pense que le problème est la :
vu que lorsque je modifie la couleur de la fenetre :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 position.w=position.h=1; for (i = 0 ; i < nrow; ++i){ for(j=0;j<ncol;++j){ position.x = j; // Les lignes sont à gauche (abscisse de 0) position.y = i; // La position verticale dépend du numéro de la ligne SDL_FillRect(ecran,&position,SDL_MapRGB(ecran->format,I[i][j],I[i][j],I[i][j])); }} SDL_Flip(ecran); pause();
La fenêtre est blanche sans l'image à l'intérieur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
Ceci fonctionne parfaitement chez moi:
Jai supprimé tous les tests d'erreur pour plus de clarté.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 #define WIDTH 1920 #define HEIGHT 2560 int main(int argc,char *argv[]) { SDL_Surface *ecran; SDL_Rect position; int i,j; double *img; img=malloc(WIDTH*HEIGHT*sizeof(double)); /* Génération des pixels */ for(i=0;i<WIDTH;i++) for(j=0;j<HEIGHT;j++) *(img+i*WIDTH+j)=rand()%256; /* Création de la fenêtre et mise en noir */ SDL_Init(SDL_INIT_VIDEO); ecran=SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF); // |SDL_RESIZABLE); SDL_FillRect(ecran,NULL,SDL_MapRGB(ecran->format,0,0,0)); /* Remplissage de la fenêtre */ position.w=position.h=1; for (i=0;i<WIDTH;++i) for(j=0;j<HEIGHT;++j) { position.x=i; position.y=j; SDL_FillRect(ecran,&position,SDL_MapRGB(ecran->format,*(img+i*WIDTH+j),*(img+i*WIDTH+j),*(img+i*WIDTH+j))); } SDL_Flip(ecran); pause(); free(img); SDL_FreeSurface(ecran); SDL_Quit(); return(0); }
Ne sachant pas comment ton tableau était construit, je ne me suis pas posé de question sur
mais es-tu bien sur de tes assignations? Car, évidemment, pour un tableau carré (133x133) une erreur ne se verra pas, mais pour un tableau rectangulaire...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 for (i = 0 ; i < nrow; ++i){ for(j=0;j<ncol;++j){ position.x = j; // Les lignes sont à gauche (abscisse de 0) position.y = i; // La position verticale dépend du numéro de la ligne
On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent
Bonjour,
Est ce que l'image est bien chargée ?
Peut on voir le code que vous utilisez ?
Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi
Ma page sur DVP
Mon Portfolio
Qui connaît l'erreur, connaît la solution.
Après avoir réfléchi sur vos derniers propos j'ai trouvé l'erreur.
Elle se situe là :
il faut intechanger nrow et ncol, ncol correspond pour moi à votre width.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ecran = SDL_SetVideoMode(nrow,ncol, 32, SDL_HWSURFACE|SDL_RESIZABLE);
Maintenant mon image dépasse la dimension de mon écran ce qui est normale.
Il n'existe pas un moyen plus simple que ce que vous avez exposé, pour pouvoir redimensionner ma fenêtre en même temps que l'image ?
J'aimerai pouvoir la regarder dans des dimensions moins grandes ?
Pensez vous que pour des opérations de traitement d'images il serait mieux d'utiliser GTK au lieu de la SDL ?
Modifier la taille de l'image n'a rien de bien sorcier. Il y a juste une étape supplémentaire: il faut construire l'image de base dans une SDL_Surface. Cette surface de base ne sera jamais modifiée, c'est par extrapolation de celle-ci que l'on génèrera une surface d'une autre taile.
Voici l'enchainement des tâches (je prends comme exemple la variable img créée dans une autre réponse):
1) Création de la surface de base
Pour afficher l'image suivant sa taille:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 /* Creation de l'image orignale */ SDL_Surface *createImg(double *img) { int i,j; SDL_Surface *simg; SDL_Rect position; simg=SDL_CreateRGBSurface(SDL_HWSURFACE,WIDTH,HEIGHT,32,0,0,0,0); position.w=position.h=1; for (i=0;i<WIDTH;++i) for(j=0;j<HEIGHT;++j) { position.x=i; position.y=j; SDL_FillRect(simg,&position,SDL_MapRGB(simg->format,*(img+i*HEIGHT+j),*(img+i*HEIGHT+j),*(img+i*HEIGHT+j))); } return(simg); }
Et pour gérer les events:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 void displayImg(SDL_Surface **ecran,SDL_Surface *src,int width,int height) { SDL_Surface *newSurf; if(*ecran!=NULL) SDL_FreeSurface(*ecran); if(src->w!=width || src->h!=height) newSurf=rotozoomSurfaceXY(src,0.,(double)width/(double)src->w,(double)height/(double)src->h,1); else newSurf=src; *ecran=SDL_SetVideoMode(newSurf->w,newSurf->h,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE); SDL_BlitSurface(newSurf,NULL,*ecran,NULL); SDL_Flip(*ecran); if(newSurf!=src) SDL_FreeSurface(newSurf); }
Enfin, le main:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 /* Traitement des event */ void treatEvent(SDL_Surface **ecran,SDL_Surface *img) { int done; SDL_Event event; done=0; while(!done) { SDL_WaitEvent(&event); switch(event.type) { case SDL_QUIT: done=1; break; case SDL_KEYDOWN: switch(event.key.keysym.sym) { case SDLK_ESCAPE: done=1; break; case SDLK_1: case SDLK_KP1: displayImg(ecran,img,WIDTH,HEIGHT); break; case SDLK_2: case SDLK_KP2: if(event.key.keysym.mod&KMOD_CTRL) displayImg(ecran,img,WIDTH*2,HEIGHT*2); else displayImg(ecran,img,WIDTH/2,HEIGHT/2); break; // // etc... // default: break; } break; case SDL_VIDEORESIZE: displayImg(ecran,img,event.resize.w,event.resize.h); break; } } }
Il faut ajouter
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 int main(int argc,char *argv[]) { SDL_Surface *ecran,*imgSurf; double *img; SDL_Init(SDL_INIT_VIDEO); img=malloc(WIDTH*HEIGHT*sizeof(double)); generateImg(img); imgSurf=createImg(img); ecran=NULL; displayImg(&ecran,imgSurf,WIDTH,HEIGHT); treatEvent(&ecran,imgSurf); free(img); SDL_FreeSurface(imgSurf); SDL_FreeSurface(ecran); SDL_Quit(); return(0); }
et linker avec la librairie
Code : Sélectionner tout - Visualiser dans une fenêtre à part #include <sdl_rotozoom.h>
Pour GTK, je n'en sais rien, je ne connais pas (encore) cette librairie (c'est dans les bagages pour l'été).
Code : Sélectionner tout - Visualiser dans une fenêtre à part sdlgfx.lib
Edgar.
On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent
Bonjour,
Je vous remercie ça fonctionne .
Cependant j'ai un petit souci avec la gestion des événements. J'aimerai savoir comment puis-je faire pour afficher que des images qui ont une résolution inférieur à celle de l'écran. C'est à dire si la résolution de l'image dépasse celle de l'écran, la taille de cette dernière devient celle de l'écran.
Tu charge l'image, tu regarde sa taille, tu la compare avec celle de l'écran, et si dans une des deux dimensions (largeur ou hauteur) elle dépasse, tu redimensionne.
Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi
Ma page sur DVP
Mon Portfolio
Qui connaît l'erreur, connaît la solution.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager