Comment inverser une image avec sdl

Soyez le premier à donner votre avis sur cette source.

Vue 14 483 fois - Téléchargée 582 fois

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

Ajouter un commentaire Commentaires
Messages postés
4
Date d'inscription
mardi 24 avril 2007
Statut
Membre
Dernière intervention
8 octobre 2009

C'est affreux toutes ces variables globale
Messages postés
30
Date d'inscription
dimanche 20 juillet 2008
Statut
Membre
Dernière intervention
7 octobre 2009
1
slt WormsParty,
le principe de ton code est bon, c'est trés utils de savoir faire des tansformations sur les pixels, je trouve que c'est bien, sauf pour le traitement des evenemnts clavier, ou tu as mis beaucoup de "IF", le "SWITCH" c'est beaucoup mieux, à+.
Messages postés
8
Date d'inscription
mercredi 24 mai 2006
Statut
Membre
Dernière intervention
27 mars 2007

Bonjour,
j'ai un probléme lorsque j'essai d'exécuter "SDL_LoadBMP" l'erreur est "identifier 'SDL_RWFromFile'"
merci d'avance!
Messages postés
168
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
21 avril 2005

tres tres mal codé...
C'est inutil de déclaré un tableau temporaire, et encore si tu veux passer par là utilise une allocation dynamique et non statique.

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.