Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C/SDL] accerir la couleur d'un pixel de la fenetre

pour un programme de "mirroir" ^^

Sujet résolu
    22 avril 2006 à 16:18:39

    (dsl de reposter un autre sujet dans la meme journée mais mon probleme a changé)

    donc REsalut :) ,

    comme le dit le titre je cherche a accerir la couleur (en RGB) d'un pixel a l'ecran

    j'ai entendu parler trés vagement de SDL_SetPixel mais je ne sais pas m'en servir et je ne pense pas que ca soit utile ici (il me semble que c'est pour cree un pixel d'un couleur a un endroit preci)

    donc en fait il me faudrait presque le contraire de SDL_SetPixel

    j'espere que ca existe sinon je vais devoir le coder moi meme :euh:

    merci ^^
    • Partager sur Facebook
    • Partager sur Twitter
      22 avril 2006 à 16:22:30

      http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetVideoMode
      http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fLockSurface
      http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSurface champ pixels
      http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fGetRGB utilise le champ format de l'appel précédent
      http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fUnlockSurface

      Et pour t'aider à localiser ton pixel : pixels[x+y*pitch]

      Et en fait si tu veux juste faire un miroir autant manipuler la surface image directement.
      Voici un code qui flip verticalement :
      SDL_Surface * flipSurface(SDL_Surface * surface)
      {
          unsigned int current_line,pitch;
          SDL_Surface * fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                         surface->w,surface->h,
                                         surface->format->BitsPerPixel,
                                         surface->format->Rmask,
                                         surface->format->Gmask,
                                         surface->format->Bmask,
                                         surface->format->Amask);



          SDL_LockSurface(surface);
          SDL_LockSurface(fliped_surface);

          pitch = surface->pitch;
          for (current_line = 0; current_line < surface->h; current_line ++)
          {
              memcpy(&((unsigned char* )fliped_surface->pixels)[current_line*pitch],
                     &((unsigned char* )surface->pixels)[(surface->h - 1  - current_line)*pitch],
                     pitch);
          }

          SDL_UnlockSurface(fliped_surface);
          SDL_UnlockSurface(surface);
          return fliped_surface;
      }
      • Partager sur Facebook
      • Partager sur Twitter
        22 avril 2006 à 16:30:29

        oulala :euh:
        c'est compliqué !

        je comprend pas :
        -pitch ?
        -une bonne partie du code :euh:

        en fait moi je voulais faire le mirroir comme ca :
        -on note toute les couleur de chaque pixel rangé dans un tableau à 2 dimension
        -on copie ces valeur dans un autre tableau à 2 dimension de la meme taille mais en partant de la fin (pour faire l'effet mirroir)
        -on affiche le resultat

        donc si tu pouvais m'expliquer un peu ce serait sympa

        merci beaucoup ^^

        • Partager sur Facebook
        • Partager sur Twitter
          22 avril 2006 à 16:37:00

          Pitch c'est la largeur réelle en mémoire d'une ligne de ton image. En vrai si elle fait 63 de large par exemple elle fera 64 pixels (dont 1 inutilisé) de large en mémoire (généralement arrondi à la puissance de 2 supérieure). Comme tu n'es pas censé savoir à l'avance il faut utiliser la variable pitch.

          Ici mon code copie ligne par ligne l'image dans une autre image en sens (verticalement parlant) inverse.

          Utilise le même code de début pour créer ta 2eme image en fonction de la premiere dans le meme format.

          Ensuite moi je vais plus vite que de lire pixel par pixel car je traite par ligne.
          Toi ce que tu fais :

          Tu vas sur x de 0 à w - 1
          tu copies pixels[x+y*pitch] dans l'autre image en [(w-x-1) + (h - y -1 )*pitch
          Puis tu completes de w à pitch -1 avec des pixels vides (0)
          Puis tu passes au y suivant

          T'expliquer plus me ferait te faire le code à ta place et j'ai pas envie.
          • Partager sur Facebook
          • Partager sur Twitter
            22 avril 2006 à 17:00:14

            j'arrive difficilement à comprendre

            merci kayl mais je pense que c'est trop compliqué pour moi (qui n'ai lu que les cours de m@teo21)

            il y aurait pas plus simple ? :euh:
            (plus simple mais pas forcement plus court ;) )




            • Partager sur Facebook
            • Partager sur Twitter
              22 avril 2006 à 17:07:35

              bouge pas...

              Image utilisateur

              Tiens cadeau :

              #ifdef __cplusplus
                  #include <cstdlib>
                   #include <cstring>
              #else
                  #include <stdlib.h>
                  #include <string.h>
              #endif
              #include <SDL/SDL.h>

              SDL_Surface * flipSurface(SDL_Surface * surface)
              {
                  unsigned int current_line,pitch;
                  SDL_Surface * fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                                 surface->w,surface->h,
                                                 surface->format->BitsPerPixel,
                                                 surface->format->Rmask,
                                                 surface->format->Gmask,
                                                 surface->format->Bmask,
                                                 surface->format->Amask);



                  SDL_LockSurface(surface);
                  SDL_LockSurface(fliped_surface);

                  pitch = surface->pitch;
                  for (current_line = 0; current_line < surface->h; current_line ++)
                  {
                      memcpy(&((unsigned char* )fliped_surface->pixels)[current_line*pitch],
                             &((unsigned char* )surface->pixels)[(surface->h - 1  - current_line)*pitch],
                             pitch);
                  }

                  SDL_UnlockSurface(fliped_surface);
                  SDL_UnlockSurface(surface);
                  return fliped_surface;
              }

              SDL_Surface * miroir(SDL_Surface * surface)
              {
                  unsigned int y,x,pitch,w,h,bytes;
                  SDL_Surface * fliped_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                                 surface->w,surface->h,
                                                 surface->format->BitsPerPixel,
                                                 surface->format->Rmask,
                                                 surface->format->Gmask,
                                                 surface->format->Bmask,
                                                 surface->format->Amask);



                  SDL_LockSurface(surface);
                  SDL_LockSurface(fliped_surface);

                  pitch = surface->pitch;
                  w = surface->w;
                  h = surface->h;
                  bytes = surface->format->BytesPerPixel;
                  for (y = 0; y < h; y ++)
                  {
                      for (x = 0; x < w; x++)
                      {
                          memcpy(&((unsigned char* )fliped_surface->pixels)[(w-1-x)*bytes + (h-1-y)*pitch],
                                 &((unsigned char* )surface->pixels)[x*bytes+y*pitch],
                                 bytes);
                      }
                      memset(&((unsigned char* )fliped_surface->pixels)[w*bytes+(h-1-y)*pitch],
                             0,
                             pitch-w*bytes);
                  }

                  SDL_UnlockSurface(fliped_surface);
                  SDL_UnlockSurface(surface);
                  return fliped_surface;
              }


              int main ( int argc, char** argv )
              {
                  SDL_Surface* screen;
                  SDL_Surface* image,* image2,*image3;
                  SDL_Rect dstrect,dstrect2,dstrect3;
                  SDL_Event event;
                  int done = 0;

                  SDL_Init(SDL_INIT_VIDEO);
                  atexit(SDL_Quit);

                  screen = SDL_SetVideoMode(640, 480, 16,
                                            SDL_HWSURFACE|SDL_DOUBLEBUF);

                  image = SDL_LoadBMP("cb.bmp");

                  dstrect.x = (screen->w - image->w) / 2;
                  dstrect.y = 10;

                  image2 = flipSurface(image);
                  dstrect2.x = (screen->w - image->w) / 2;
                  dstrect2.y = 10 + 5+ image->h;

                  image3 = miroir(image);
                  dstrect3.x = (screen->w - image->w) / 2;
                  dstrect3.y = 10 + 5 + 5 + 2* image->h;

                  SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
                  SDL_BlitSurface(image, 0, screen, &dstrect);
                  SDL_BlitSurface(image2, 0, screen, &dstrect2);
                  SDL_BlitSurface(image3, 0, screen, &dstrect3);
                  SDL_Flip(screen);

                  while (done == 0)
                  {
                      SDL_WaitEvent(&event);
                      // check for messages
                      switch (event.type)
                      {
                          // exit if the window is closed
                          case SDL_QUIT:
                          done = 1;
                          break;
                      }

                  }

                  SDL_FreeSurface(image3);
                  SDL_FreeSurface(image2);
                  SDL_FreeSurface(image);
                  return 0;
              }



              Le code est un peu compliqué car il ne fait aucune hypothèse initiale sur le format utilisé.


              Le memset utilisé vient mettre les pixels non utilisés (truc du pitch) à 0. "empty surface" n'est pas assez précis pour moi dans l'aide de SDL_CreateRGBSurface donc je sais pas vraiment si ils sont nuls eux, à la base. M'enfin c'est pas le plus important du code.

              Et petit rectification par rapport à ce que j'ai dis en fait le pitch c'est le nombre de bytes réel par ligne pas le nombre de pixel (mais c'est pas pour autant que largeur*bytes/pixel = pitch ! il peut tjs y avoir le coup du ^2, j'ai pas envie de faire d'hypothèse perso)
              • Partager sur Facebook
              • Partager sur Twitter
                23 avril 2006 à 11:07:31

                wouhahou !!!

                :D merci beaucoup kayl c'est super sympa

                je vais analyser ton code pour le comprendre (j'espere :p )

                aller => probleme resolu :)

                encore merci :D

                EDIT ! : c bon je comprend ton code (enfin une bonne partie :) ) je l'ai meme un peu modifier pour avoir 4 image et la fenetre a la taille de ses 4 images (+ un titre, + une icone ...) :

                Image utilisateur


                encore trop merci :)

                ps : si tu veux le code demande ;) (tu as quand meme les droit d'auteur :p )
                • Partager sur Facebook
                • Partager sur Twitter

                [C/SDL] accerir la couleur d'un pixel de la fenetre

                × 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