Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème modification taille d'une image avec SDL2

Sujet résolu
    15 juin 2023 à 6:18:59

    Bonjour, j'ai un problème quand je modifie la taille d'une image avec SDL2

    Image normal d'un personnage fait vite fait sur paint (je pense que sa se voit) : 

    Même personnage mais avec la taille qui a été modifier : 

    Enfaite quand je modifie la taille "w" de l'image sa clone le personnage et quand je modifie la taille "h" de 'l'image sa me fait apparaitre plein de pixel en dessous du personnage. Je ne sais pas d'où viens le problème, c'est peut être car j'utilise la mauvaise manière pour modifier la taille de l'image mais si ces sa alors comme modifier la taille de l'image autrement.

    Voici mon code : 

    #include <exception>
    #include <string>
    #include <iostream>
    #include <SDL.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char* argv[])
    {
       SDL_Window *window = NULL;
       SDL_Renderer *renderer = NULL;
       SDL_Event event;
       SDL_Texture *texture, *textureCopy = NULL;
       SDL_bool quit = SDL_FALSE;
       SDL_Surface *surface = NULL;
       int statue = EXIT_FAILURE;
    
       if(0 != SDL_Init(SDL_INIT_VIDEO))
       {
           fprintf(stderr, "Erreur SDL_Init() : %s", SDL_GetError());
           goto Quit;
       }
    
       window = SDL_CreateWindow("Jeux", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_RESIZABLE);
       if(NULL == window)
       {
           fprintf(stderr, "Erreur SDL_CreateWindow() : %s", SDL_GetError());
           goto Quit;
       }
    
       renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
       if(NULL == renderer)
       {
           fprintf(stderr, "Erreur SDL_CreateRenderer() : %s", SDL_GetError());
           goto Quit;
       }
    
       surface = SDL_LoadBMP("test.bmp");
       if(NULL == surface)
       {
           fprintf(stderr, "Erreur SDL_LoadBMP() : %s", SDL_GetError());
           goto Quit;
       }
    
       surface->w = 100;
       surface->h = 100;
    
       SDL_RenderClear(renderer);
    
       texture = SDL_CreateTextureFromSurface(renderer, surface);
       if(texture == NULL)
       {
           fprintf(stderr, "Erreur SDL_CreateTextureFromSurface() : %s", SDL_GetError());
           goto Quit;
       }
    
       textureCopy = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, surface->w, surface->h);
       if(NULL == textureCopy)
       {
           fprintf(stderr, "Erreur SDL_CreateTexture() : %s", SDL_GetError());
           goto Quit;
       }
    
       SDL_SetRenderTarget(renderer, textureCopy);
       SDL_RenderCopy(renderer, texture, NULL, NULL);
       SDL_SetRenderTarget(renderer, NULL);
       SDL_RenderCopy(renderer, texture, NULL, NULL);
       SDL_RenderPresent(renderer);
       SDL_FreeSurface(surface);
    
       while(!quit)
       {
           SDL_WaitEvent(&event);
           if(event.type == SDL_QUIT)
            quit = SDL_TRUE;
       }
    
       statue = EXIT_SUCCESS;
    
       Quit:
    
           if(NULL != textureCopy)
            SDL_DestroyTexture(textureCopy);
           if(NULL != texture)
            SDL_DestroyTexture(texture);
           if(NULL != renderer)
            SDL_DestroyRenderer(renderer);
           if(NULL != window)
            SDL_DestroyWindow(window);
           SDL_Quit;
    }

    C'est un peut le bazar mais n'y faite pas attention je modifierais tous sa pour que se soit plus propre quand j'aurais réussis à faire fonctionne la modification de l'image correctement. (désoler pour les fautes d'orthographes si il y en a (et il y en a très probablement))

    • Partager sur Facebook
    • Partager sur Twitter
      15 juin 2023 à 7:42:35

      > le bazar

      C'est pas quand ça marchera qu'il faudra que ça soit propre.

      Tu en as besoin pour mieux t'y retrouver, surtout quand tu y cherches des erreurs, avant que ça marche.

      Pour changer la taille j'imagine qu'il faut construire un autre bmp, avec son propre tableau de pixels.

      -
      Edité par michelbillaud 15 juin 2023 à 7:45:05

      • Partager sur Facebook
      • Partager sur Twitter
        15 juin 2023 à 18:38:37

        Hello,

        Pourquoi veux-tu redimensionner ton bmp ? Car si c'est juste pour réduire ou agrandir l'image lors de l'affichage, il suffit de jouer sur les variables w et h de destrect (le dernier paramètre de SDL_RenderCopy).

        De toute façon, ta manière de faire en modifiant w et h de l'image ne fonctionnera pas: les pixels de l'image sont rangés à la queue-leu-leu, et modifier une dimension te fera taper un peu n'importe où dans cette zone de pixels.

        Edit: si tu veux vraiment diminuer / agrandir la taille de l'image, je pense qu'une manière de faire (peut-être la seule ?) est de créer une nouvelle surface ayant la dimension voulue, d'appeler SDL_BlitScaled() et de créer une texture à partir de cette nouvelle surface. Je n'ai jamais essayé.

        Edit à l'édit: j'ai essayé, ça fonctionne. Demmmmaaandeeeez le programme :D  

        -
        Edité par edgarjacobs 16 juin 2023 à 0:39:27

        • Partager sur Facebook
        • Partager sur Twitter

        On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

          16 juin 2023 à 8:27:24

          C'est bon j'ai réussis en créant un rectangle et en remplaçant le NULL de "SDL_Rect* dstrect" du deuxième "SDL_Render_Copy" par la taille du rectangle. Sinon michelbillaud je vois pas se que tu vois pas se que tu veux dire par construire un autre bmp, sa voulait dire faire une nouvelle image ou copier une nouvelle image sur ma texture ou sur une nouvelle texture, et pour les tableau de pixels j'ai pas encore appris se que c'étais, j'y verrais bientôt.

          Par contre est ce que quelqu'un sais comment modifier la position de la texture lorsque l'on appuie sur une touche car j'ai essayer plusieurs chose mais sa ne fonctionne pas.(désoler d'avoir mis du temps à répondre)

          • Partager sur Facebook
          • Partager sur Twitter
            16 juin 2023 à 15:16:30

            MorgadPrudhon a écrit:

            Par contre est ce que quelqu'un sais comment modifier la position de la texture lorsque l'on appuie sur une touche car j'ai essayer plusieurs chose mais sa ne fonctionne pas.(désoler d'avoir mis du temps à répondre)

            Ben oui, il suffit de modifier le x et/ou le y de destrect. Ne pas oublier d'effacer le renderer avant de faire le RenderCopy.

            Et ce que michelbillaud proposait, c'est ceci: (enfin, je pense)

            	#define REDIM_SCALE	(1./2)		// par exemple
            	
            	SDL_Surface *srf=SDL_LoadBMP("image.bmp");
            	SDL_Surface *redim=SDL_CreateRGBSurface(0,srf->w*REDIM_SCALE,srf->h*REDIM_SCALE,32,0,0,0,0);
            	SDL_BlitScaled(srf,NULL,redim,NULL);
            	SDL_Texture *txtr=SDL_CreateTextureFromSurface(rdr,redim);
            




            -
            Edité par edgarjacobs 16 juin 2023 à 15:19:27

            • Partager sur Facebook
            • Partager sur Twitter

            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

              16 juin 2023 à 15:36:33

              ouai j'ai essayer de faire sa mais sa marche pas, enfin je pense que se que j'arrive pas c'est surtout mettre à jour la texture car sinon modifier la valeur de la position x et y du triangle c'est pas dur, mais j'ai essayer en faisant SDL_RenderPresent pour mettre à jour le renderer après l'appui de la touche sa marche pas, j'ai essayer en mettant SDL_RenderCopy pour que sa me recopie la texture avec la nouvelle position du rectangle mais sa marche pas.
              • Partager sur Facebook
              • Partager sur Twitter
                16 juin 2023 à 19:41:58

                créer la texture
                mettre la texture dans le renderer
                afficher le renderer
                
                tant que pas fini
                	attendre un évènement
                	si appui sur la flèche gauche ....
                	si appui sur la flèche droite ....
                	si appui sur la flèche haut ....
                	si appui sur la flèche bas ....
                	effacer le renderer
                	mettre la texture dans le renderer
                	afficher le renderer


                Et "ça marche pas" n'est pas une bonne information....

                Edit: et si tu postais du code ?

                -
                Edité par edgarjacobs 16 juin 2023 à 19:48:20

                • Partager sur Facebook
                • Partager sur Twitter

                On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                  16 juin 2023 à 20:26:51

                  while(!quit)
                     {
                         SDL_WaitEvent(&event);
                         if(event.type == SDL_QUIT)
                          quit = SDL_TRUE;
                              if(event.type == SDL_KEYDOWN)
                          {
                              if(event.key.keysym.sym == SDLK_d)
                              {
                              x++;
                              SDL_RenderClear(renderer);
                              SDL_SetRenderTarget(renderer, textureCopy);
                              SDL_RenderCopy(renderer, texture, NULL, NULL);
                              SDL_SetRenderTarget(renderer, NULL);
                              SDL_RenderCopy(renderer, texture, NULL, &rect);
                              SDL_RenderPresent(renderer);
                              }
                          }
                     }

                  Je mets juste cette partie du code car je pense qu'il n'y a pas vraiment besoin du code en entier, je pense que l'endroit qui fait que j'arrive pas a faire bouger le personnage c'est quand j'essayer de recopier la texture sur le renderer, pourtant je le fait comme je l'ai fait la premier fois dans le code.

                  Le "rect" c'est le nom de mon triangle, le "x" c'est la valeur x de mon triangle, "renderer" c'est le nom de mon renderer et "texture" et "textureCopy" se sont le nom de mes textures.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 juin 2023 à 20:40:12

                    Déjà, supprime les lignes 12, 13 et 14 qui ne servent à rien (et tu n'as vraissemblablement pas besoin de textureCopy).

                    Ensuite:

                    MorgadPrudhon a écrit:

                    ouai j'ai essayer de faire sa mais sa marche pas, enfin je pense que se que j'arrive pas c'est surtout mettre à jour la texture car sinon modifier la valeur de la position x et y du triangle c'est pas dur

                    Faut croire que si. A ton avis, quel x dois-tu modifier ? Relis mon post.

                    -
                    Edité par edgarjacobs 16 juin 2023 à 20:46:08

                    • Partager sur Facebook
                    • Partager sur Twitter

                    On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                      16 juin 2023 à 20:57:27

                      J'ai supprimer les ligne 12, 13 et 14 mais sa ne marche toujours pas, et tu me dis qu'il faut modifier le x de destrect mais destrect utilise les valeurs de mon rectangle (car oui c'est un rectangle que j'ai crée, je sais pas pourquoi depuis le début je dis triangle, mais je pense que tu avais compris que je parlais d'un rectangle), donc la valeur x de destrect c'est la valeur x de mon rectangle. Par contre quand tu dis destrect tu parles bien de dstrect, car moi sur mon logiciel (codeBlocks) c'est marquer dstrect et pas destrect.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        16 juin 2023 à 23:26:49

                        destrect, dstrect, destrct, dstrct: on a compris qu'on parle du 4ème paramètre de la fonction.

                        Et oui, c'est bien le x de dstrect (dans ton cas rect.x) qu'il faut modifier.

                        Un exemple: (ce code ne teste pas la collision avec les bords de la fenêtre)

                        #define WND_SIZE_HORZ			400
                        #define WND_SIZE_VERT			600
                        
                        SDL_Surface *srf=SDL_LoadBMP("ball3.bmp");
                        SDL_Texture *ball=SDL_CreateTextureFromSurface(rdr,srf);
                        SDL_Rect r={(WND_SIZE_HORZ-srf->w)/2, (WND_SIZE_VERT-srf->h)/2, srf->w, srf->h};
                        DisplayTxtr(rdr,ball,&r);
                        bool done=false;
                        while(!done) {
                        	SDL_Event event;
                        	while(SDL_PollEvent(&event))
                        		if(event.type==SDL_KEYDOWN) {
                        			switch(event.key.keysym.sym) {
                        				case SDLK_ESCAPE: done=true; break;
                        				case SDLK_UP: r.y--; break;
                        				case SDLK_RIGHT: r.x++; break;
                        				case SDLK_DOWN: r.y++; break;
                        				case SDLK_LEFT: r.x--; break;
                        				default: break;
                        			}
                        			DisplayTxtr(rdr, ball, &r);
                        		}
                        }


                         

                        -
                        Edité par edgarjacobs 17 juin 2023 à 0:26:40

                        • Partager sur Facebook
                        • Partager sur Twitter

                        On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                          17 juin 2023 à 0:11:48

                          Bon j'ai réussi à résoudre le problème, enfaite c'était extrêmement simple (à régler pas à trouver (en tous cas pas pour moi)), la raison c'était que pour modifier la valeur x du rectangle (et donc de la texture) il ne fallait pas que j'utilise une variable que j'avais crée (dans mon code, la variable "x") mais rect.x, je sais pas trop comment sa se fait mais bon sa fonctionne donc sa me va, et c'est grâce à ta réponse que j'ai réussi car quand tu as parler de rect.x, je me suis demander se que sa faisais si je mettais rect.x++ au lieu de x++, et sa a marcher, donc merci.(désoler si tu n'a pas tous compris je suis nul pour expliquer les choses)

                          Sinon pour le code que tu as fait, je l'ai pas vraiment bien compris. C'est quoi DisplayTxTr? C'est quoi SDL_PollEvent. C'est quoi switch et case. Désoler si il y a beaucoup de chose dans le code que je ne comprend pas, je connais juste les fonctions de bases du langages C et de la SDL.

                          En tous cas merci de m'avoir aider.

                          -
                          Edité par MorgadPrudhon 17 juin 2023 à 0:12:12

                          • Partager sur Facebook
                          • Partager sur Twitter
                            17 juin 2023 à 0:25:47

                            MorgadPrudhon a écrit:

                            C'est quoi SDL_PollEvent. C'est quoi switch et case. Désoler si il y a beaucoup de chose dans le code que je ne comprend pas, je connais juste les fonctions de bases du langages C et de la SDL.

                            Avant de s'attaquer à sdl, il est conseillé de suivre un tutoriel sur le langage C. Et switch est une des instructions de base du langage.

                            DisplayTxtr() est une fonction de mon programme, qui permet d'aficher une texture. Elle n'avait pas besoion d'être explicitée ici. Mais si tu veux le code au complet:

                            #include <sdl2/sdl.h>
                            #include <stdbool.h>
                            
                            #define UNUSED(x)				(void)(x)
                            #define WND_SIZE_HORZ			400
                            #define WND_SIZE_VERT			600
                            #define WND_COLOR_R				50
                            #define WND_COLOR_G				100
                            #define WND_COLOR_B				150
                            #define WND_TITLE				"move sdl 2.x"
                            #define RDR_DEFAULT_DRIVER		-1
                            
                            
                            void ClearRDR(SDL_Renderer *rdr) {
                            	SDL_SetRenderDrawColor(rdr, WND_COLOR_R, WND_COLOR_G, WND_COLOR_B, SDL_ALPHA_OPAQUE);
                            	SDL_RenderClear(rdr);
                            }
                            
                            
                            void DisplayTxtr(SDL_Renderer *rdr, SDL_Texture *txtr, SDL_Rect *coo) {
                            	ClearRDR(rdr);
                            	SDL_RenderCopy(rdr, txtr, NULL, coo);
                            	SDL_RenderPresent(rdr);
                            }
                            
                            
                            /* 
                              Impossible de mettre ball3.bmp sur le site (ajouter une image donne: This file is not a valid image).
                              Le fichier est disponible ici:  https://uptobox.com/qj4mezyd7y76
                            */
                            int main(int argc, char *argv[]) {
                            	UNUSED(argc);
                            	UNUSED(argv);
                            	SDL_Init(SDL_INIT_VIDEO);
                            	SDL_Window *wnd=SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WND_SIZE_HORZ, WND_SIZE_VERT, SDL_WINDOW_SHOWN);
                            	SDL_Renderer *rdr=SDL_CreateRenderer(wnd, RDR_DEFAULT_DRIVER, SDL_RENDERER_ACCELERATED);
                            
                            	SDL_Surface *srf=SDL_LoadBMP("ball3.bmp");
                            	SDL_Texture *ball=SDL_CreateTextureFromSurface(rdr, srf);
                            	SDL_Rect r={(WND_SIZE_HORZ-srf->w)/2, (WND_SIZE_VERT-srf->h)/2, srf->w, srf->h};
                            	DisplayTxtr(rdr, ball, &r);
                            	bool done=false;
                            	while(!done) {
                            		SDL_Event event;
                            		while(SDL_PollEvent(&event))
                            			if(event.type==SDL_KEYDOWN) {
                            				switch(event.key.keysym.sym) {
                            					case SDLK_ESCAPE: done=true; break;
                            					case SDLK_UP: r.y-=5; break;
                            					case SDLK_RIGHT: r.x+=5; break;
                            					case SDLK_DOWN: r.y+=5; break;
                            					case SDLK_LEFT: r.x-=5; break;
                            					default: break;
                            				}
                            				DisplayTxtr(rdr, ball, &r);
                            			}
                            		SDL_Delay(2);
                            	}
                            
                            	SDL_DestroyTexture(ball);
                            	SDL_FreeSurface(srf);
                            	SDL_DestroyRenderer(rdr);
                            	SDL_DestroyWindow(wnd);
                            	SDL_Quit();
                            	
                            	return(0);
                            }





                            -
                            Edité par edgarjacobs 17 juin 2023 à 1:09:04

                            • Partager sur Facebook
                            • Partager sur Twitter

                            On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                              17 juin 2023 à 0:48:04

                              Ok là j'ai déjà mieux compris le code, et pour switch sois c'est une fonction que je n'avais pas appris dans mon cour, sois c'est une fonction d'on je n'ai jamais eu besoin donc j'ai oublier son existence. Et merci encore pour l'aide.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                17 juin 2023 à 1:00:12

                                switch n'est pas une fonction, mais une instruction du langage. Le langage C ne fournit aucune fonction, seules les librairies en apportent.
                                • Partager sur Facebook
                                • Partager sur Twitter

                                On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                  19 juin 2023 à 0:56:29

                                  Question philosophique, les fonctions de la bibliothèque standard C font-elle partie du langage C ?

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    19 juin 2023 à 1:48:10

                                    Hello Michel,

                                    Pas pour moi. Comme tu le dis, c'est une bibliothèque. Et qui plus est, elle a plusieurs implémentations pour une même version du C. Mais heureusement qu'elle existe ! Je me vois mal aller coder les i/o par exemple.

                                    -
                                    Edité par edgarjacobs 19 juin 2023 à 1:53:36

                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                                      19 juin 2023 à 4:17:45

                                      > Question philosophique, les fonctions de la bibliothèque standard C font-elle partie du langage C ?


                                      Elles ne font pas partie du langage en soi, même si on les enseigne dans les cours de programmation en C.


                                      Ce n'est pas avec un  do ... while  qu'on va afficher un "Hello World!"


                                      Il faut bien utiliser la fonction printf (ou une autre), Il y a des gens qui ont recodé le printf à leur façon.


                                      Le langage C nous apprend comment écrire des fonctions et à les appeler.


                                      En théorie, toutes les fonctions d'une bibliothèque pourraient être écrites en C.


                                      En pratique, c'est souvent différent, surtout pour les accès aux ressources comme les disques ou le port Internet ...

                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Le Tout est souvent plus grand que la somme de ses parties.

                                        19 juin 2023 à 10:38:38

                                        PierrotLeFou a écrit:

                                        Elles ne font pas partie du langage en soi, même si on les enseigne dans les cours de programmation en C.

                                        Elles sont décrite dans la norme chapitre 7. Library
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        ...
                                          19 juin 2023 à 12:16:17

                                          La preuve que la bibliothèque standard ne fait pas partie du langage, c'est qu'il existe des compilateurs C sans la bibliothèque standard.

                                          Non ?

                                          Ben alors ça fait partie du langage.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            19 juin 2023 à 12:42:49

                                            Bon, la réponse était facile

                                            Le groupe de travail nommé jtc1/sc22/wg14/ https://www.open-std.org/jtc1/sc22/wg14/ établit un standard international pour le langage C.

                                            Et ce document comporte

                                            • le standard du langage
                                            • et la description des bibliothèques standards
                                            Le brouillon du dernier standard est accessible ici https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf
                                            Le langage est dans le chapitre 6, la bibliothèque dans le 7.
                                            En fait le groupe de travail produit plusieurs standards, parce qu'il y a le C embarqué, des extensions etc.

                                            -
                                            Edité par michelbillaud 19 juin 2023 à 12:48:11

                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Problème modification taille d'une image avec SDL2

                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                            • Editeur
                                            • Markdown