Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SDL] Couleur exacte d'un pixel

Sujet résolu
    30 août 2007 à 17:35:09

    Bonjour
    J'aimerai pouvoir afficher une image exactement comme elle est sans l'afficher o_O , juste en affichant l'affichant pixel par pixel (pour des test). Mais quand j'essaye, le résultat est pour le moins médiocre:

    Image utilisateur

    Donc j'aimerai savoir si le problème vient de mon code ou pas et s'il existe une meilleure fonction que celle que j'utilise pour arriver à mes fins.
    Voilà mon code:

    1. Uint32 getpixel(SDL_Surface *surface, int x, int y);
    2. void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
    3. int main ( int argc, char** argv )
    4. {
    5.     // initialize SDL video
    6.     SDL_Init(SDL_INIT_VIDEO);
    7.     // create a new window
    8.     SDL_Surface* screen = SDL_SetVideoMode(480, 272, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
    9.     // load an image
    10.     SDL_Surface* bmp = IMG_Load("1.png");
    11.     // program main loop
    12.     bool done = false;
    13.     while (!done)
    14.     {
    15.         // message processing loop
    16.         SDL_Event event;
    17.         while (SDL_PollEvent(&event))
    18.         {
    19.             // check for messages
    20.             switch (event.type)
    21.             {
    22.                 // exit if the window is closed
    23.             case SDL_QUIT:
    24.                 done = true;
    25.                 break;
    26.                 // check for keypresses
    27.             case SDL_KEYDOWN:
    28.                 {
    29.                     // exit if ESCAPE is pressed
    30.                     if (event.key.keysym.sym == SDLK_ESCAPE)
    31.                         done = true;
    32.                     break;
    33.                 }
    34.             } // end switch
    35.         } // end of message processing
    36.         // clear screen
    37.         SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
    38.         SDL_LockSurface(screen);
    39.         SDL_LockSurface(bmp);
    40.         // draw bitmap
    41.         for (int i = 0; i < bmp->w; i++)
    42.         {
    43.             for (int j = 0; j < bmp->h; j++)
    44.             {
    45.                 setPixel(screen, i, j, getpixel(bmp, i, j));
    46.             }
    47.         }
    48.         SDL_UnlockSurface(bmp);
    49.         SDL_UnlockSurface(screen);
    50.         // DRAWING ENDS HERE
    51.         // finally, update the screen :)
    52.         SDL_Flip(screen);
    53.     } // end main loop
    54.     // free loaded bitmap
    55.     SDL_FreeSurface(bmp);
    56.     // all is well ;)
    57.     return 0;
    58. }
    59. Uint32 getpixel(SDL_Surface *surface, int x, int y)
    60. {
    61.     int bpp = surface->format->BytesPerPixel;
    62.     /* Here p is the address to the pixel we want to retrieve */
    63.     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
    64.     switch(bpp) {
    65.     case 1:
    66.         return *p;
    67.     case 2:
    68.         return *(Uint16 *)p;
    69.     case 3:
    70.         if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
    71.             return p[0] << 16 | p[1] << 8 | p[2];
    72.         else
    73.             return p[0] | p[1] << 8 | p[2] << 16;
    74.     case 4:
    75.         return *(Uint32 *)p;
    76.     default:
    77.         return 0;       /* shouldn't happen, but avoids warnings */
    78.     }
    79. }
    80. void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
    81. {
    82.     int bpp = surface->format->BytesPerPixel;
    83.     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
    84.     switch(bpp) {
    85.     case 1:
    86.         *p = pixel;
    87.         break;
    88.     case 2:
    89.         *(Uint16 *)p = pixel;
    90.         break;
    91.     case 3:
    92.         if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
    93.             p[0] = (pixel >> 16) & 0xff;
    94.             p[1] = (pixel >> 8) & 0xff;
    95.             p[2] = pixel & 0xff;
    96.         } else {
    97.             p[0] = pixel & 0xff;
    98.             p[1] = (pixel >> 8) & 0xff;
    99.             p[2] = (pixel >> 16) & 0xff;
    100.         }
    101.         break;
    102.     case 4:
    103.         *(Uint32 *)p = pixel;
    104.         break;
    105.     }
    106. }




    Merci d'avance ;)

    • Partager sur Facebook
    • Partager sur Twitter
      30 août 2007 à 17:45:30

      je vois que tu initialise ton screen a 16 bpp.
      Et ton image BMP, combien fait elle de bpp ?

      Essaie de mettre pareil pour les deux (déja pour essayer !)

      Edit : en effet, les fonctions getpixel et setpixel te renverront un ulong codé différemment selon la prodondeur de pixels de l'image. je te conseille donc vivement de travailler dans les memes profondeur pour chaque image :)
      Par exemple, vérifie ce que te renvoie IMG_Load au niveau des bpp (je vote pour un 24 ou un 32), et met pareil pour screen :)
      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        30 août 2007 à 21:12:07

        Ah oui ! Merci, j'avais pas vu :-°
        Maintenant, l'image est comme ceci:
        Image utilisateur
        Faut avouer que ça rend déjà beaucoup mieux :lol:
        Mais j'ai comme l'impression que le rouge et le bleu sont inversés o_O
        Voici l'image originale:
        Image utilisateur


        Encore un truc "bizarre": quand je fais "int bpp = bmp->format->BytesPerPixel; ", bpp est égal à 3.


        Edit: problème résolu. Une des solutions possible consistait à enlever la condition suivante:
        1. if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
        2.             return p[0] << 16 | p[1] << 8 | p[2];
        3.         else
        4.             return p[0] | p[1] << 8 | p[2] << 16;


        et de la remplacer par:

        1. return p[0] << 16 | p[1] << 8 | p[2];


        Voilà, c'est tout :)
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          30 août 2007 à 21:54:24

          Tu dis :
          "Encore un truc "bizarre": quand je fais "int bpp = bmp->format->BytesPerPixel; ", bpp est égal à 3."

          Il n'y a rien de "bizard". 3 Bytes = 24 Octets, ou 24 bits.
          • Partager sur Facebook
          • Partager sur Twitter
            30 août 2007 à 22:16:49

            Oups, j'ai confondu bits et bytes ^^. Mais bon, le problème ne venait pas de là.
            • Partager sur Facebook
            • Partager sur Twitter

            [SDL] Couleur exacte d'un pixel

            × 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