Comment inverser une image avec sdl

Description

Comme son nom l'indique, ce code sers à montrer comment inverser une image chargée avec la fonction SDL_LoadBMP(). Le ZIP contient un bitmap à charger et le code source. Celui-ci peut être utile pour ne pas prévoir toujours les images deux fois une fois normale et une fois inversée dans un toujours trop gros bitmap. Vous remarquerez que le bitmap se décale de quelques pixels en s'inversant...juste un tout petit truc à corriger ;-)
Le code le voici :

Source / Exemple :


#include <SDL/sdl.h>
#include <stdlib.h>

SDL_Surface *ecran; // surface de l'écran

SDL_Surface *image; // surface de l'image 1
SDL_Surface *imageM; // idem pour l'inage inversée

float xpos = 320; // position X de l'image
float ypos = 240; // idem mais Y

float xpos2 = 420; // position X de l'image
float ypos2 = 340; // idem mais Y

int direction; // si 0 -> gauche ; si 1 -> droite

int X1; // pour le renversement
int X2; // idem
int Y1; // idem
int Y2; // idem

int image_1;

int loop; // tant que vaut 0 la boucle (plus bas) sera active

Uint32 tableau[100][100]; // prévois assez grand un tableau pour mettre les valeurs RGB des pixels de vos images

// COMMENT INVERSER UNE IMAGE
// Par WORMSPARTY avec l'aide de moi1392

// Fonctions de chargement et placement de pixels

// get pixels ( ALLER CHERCHER les couleurs d'un pixel à X et Y ) 

Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;

    case 2:
        return *(Uint16 *)p;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
        return *(Uint32 *)p;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

// put pixels ( PLACER les couleurs à un pixel à X et Y ) 

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:

  • p = pixel;
break; case 2:
  • (Uint16 *)p = pixel;
break; case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { p[0] = (pixel >> 16) & 0xff; p[1] = (pixel >> 8) & 0xff; p[2] = pixel & 0xff; } else { p[0] = pixel & 0xff; p[1] = (pixel >> 8) & 0xff; p[2] = (pixel >> 16) & 0xff; } break; case 4:
  • (Uint32 *)p = pixel;
break; } } void mir_oir(SDL_Surface *point) // fonction pour inverser une image (effet miroir) //il suffit d'entrer une Surface et il l'inverse tout seul ;) { SDL_LockSurface(point); // on bloque l'accès aux autres fonctions for ( X1 = 0; X1 < point->w ; X1++) // pour chaque X de l'image { for ( Y1 = 0; Y1 < point->h ; Y1++) // pour chaque Y de l'image { tableau[X1+1][Y1+1] = getpixel(point,X1,Y1); // on va chercher les pixels } } for ( X2 = 0 ; X2 < point->w ; X2++) // pour chaque X { for ( Y2 = 0 ; Y2 < point->h ; Y2++) // pour chaque Y { putpixel(point,X2,Y2,tableau[point->w-X2][Y2+1]); // on met les pixels, mais avec les X inversés } } SDL_UnlockSurface(point); // on débloque l'accès } void event_e() // test d'évenements { SDL_Event event; if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) // si veux quitter : { exit(3); // on quitte } if (event.type == SDL_KEYDOWN) // si une touche est appuyée { if (event.key.keysym.sym == SDLK_ESCAPE) // et que celle-ci est echape { exit(4); // on quitte } if (event.key.keysym.sym == SDLK_LEFT) // si on appuie sur gauche { direction = 1; // on tourne à gauche xpos -= 1; // on déplace d'un pixel à gauche } if (event.key.keysym.sym == SDLK_RIGHT) // si droite est appuyé { direction = 0; // on tourne à droite ! xpos += 1; // on déplace d'un pixel } } } } void draw_img(SDL_Surface *point,float x,float y) // fonction de dessin { SDL_Rect rec; //précarré rec.x = (int)x; // mise du carré à X rec.y = (int)y; // idem à Y SDL_SetColorKey(point, SDL_SRCCOLORKEY, SDL_MapRGB(point->format, 0, 0, 0)); // transparence == noir SDL_BlitSurface(point, NULL, ecran, &rec); // on dessine à l'écran avec l'image renvoyée au paravent } int main(int argc,char *argv[]) // fonction principale { if (SDL_Init(SDL_INIT_VIDEO)< 0) // initiation de la video { exit(1); // si écoue -> quitte } ecran = SDL_SetVideoMode(640,480,32,SDL_HWSURFACE); // mise de la résolution à 640 x 480 à 32 bits SDL_WM_SetCaption("Inverser une image à l'écran - Par WormsParty",NULL); // mise du titre image = SDL_LoadBMP("1.bmp"); // charge l'image 1 imageM = SDL_LoadBMP("1.bmp"); // charge l'image 1 mir_oir(imageM); // mais cette fois-ci l'inverse if (!image || !ecran || !imageM ) // si le changement de résolution ou le chargement de l'image a échoué : { exit(2); // on quitte } while(!loop) // tant que le boucle est active { if (direction) // si il est tourné { draw_img(imageM,xpos,ypos); // on dessine l'image (inversée précédement) à X et Y (ici à 320 et 240 ) } else // si il n'est pas tourné { draw_img(image,xpos,ypos); // on dessine l'image normale à X et Y (ici à 320 et 240 ) } event_e(); // test des évenements SDL_Flip(ecran); } }

Conclusion :


Je remercie moi1392 qui m'a grandement aidé lors de la réalisation de ce code ;-)

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.