IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Copié un image bmp 8bits [SDL 1.2]


Sujet :

SDL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 431
    Points : 172
    Points
    172
    Par défaut Copié un image bmp 8bits
    Bonjour, j'aimerai sauvegarder un sprite 8 bits BMP? pour cela j'ai utilisé 2 méthode mais elles ne marchent pas et je n'arrive pas a trouver la solution.
    Voici les 2 méthodes :

    1er methode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    int save_spr(SDL_Surface* spr,init_sdl* J)
    {
      int i, j;
      SDL_Color colors[256];
     
      int bpp = 8;
      u8 rmask = 0;
      u8 gmask = 0;
      u8 bmask = 0;
      u8 amask = 0;
     
      SDL_Surface* CpySpr = SDL_CreateRGBSurface(SDL_HWSURFACE,spr->w,spr->h,bpp,rmask,gmask,bmask,amask);
     
     if( !(malloc_error(CpySpr,NULL)))
        {
          FILE_ERROR;LINE_ERROR;
          return -1;
        }
     
      u8* CpyPix=(u8*)CpySpr->pixels;
      u8* Pix=(u8*)spr->pixels;
     
      for(i=0;i<256;i++)
        {
          colors[i].r=i;
          colors[i].g=i;
          colors[i].b=i;
          colors[i].unused=0;
        }
     
      SDL_SetPalette(CpySpr, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
     
      for(j=0;j<spr->h;j++)
        for(i=0;i<spr->w;i++)            
          *(CpyPix+i+CpySpr->pitch*j) = *(Pix+i+spr->pitch*j);
     
      SDL_BlitSurface(CpySpr,NULL,J->screen,0);
      SDL_Flip(J->screen);
     
      return 0;
    }
    Voici le resultat :

    Nom : cpyBMPmethode1.png
Affichages : 178
Taille : 3,7 Ko

    et :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    int save_spr(SDL_Surface* spr,init_sdl* J)
    {
      int i, j;
      SDL_PixelFormat *fmt;
      SDL_Color *color;
     
      u8 index;
     
    fmt=spr->format;
     
    if(fmt->BitsPerPixel!=8){
      fprintf(stderr, "Not an 8-bit surface.\n");
      return(-1);
    }
     
    SDL_LockSurface(spr);
     
    index=*(u8 *)spr->pixels;
    color=&fmt->palette->colors[index];
     
    SDL_UnlockSurface(spr);
     
    int bpp = 8;
    u8 rmask = color->r;
    u8 gmask = color->g;
    u8 bmask = color->b;
    u8 amask = 0;
     
    SDL_Surface* CpySpr =
                            SDL_CreateRGBSurface(SDL_HWSURFACE,spr->w,spr->h,bpp,rmask,gmask,bmask,amask);
     
     if( !(malloc_error(CpySpr,NULL)))
        {
          FILE_ERROR;LINE_ERROR;
          return -1;
        }
     
     u8* CpyPix=(u8*)CpySpr->pixels;
     u8* Pix=(u8*)spr->pixels;
     
      for(j=0;j<spr->h;j++)
        for(i=0;i<spr->w;i++)            
        *(CpyPix+i+CpySpr->pitch*j) = *(Pix+i+spr->pitch*j);
     
      SDL_BlitSurface(CpySpr,NULL,J->screen,0);
      SDL_Flip(J->screen);
     
      return 0;
    }
    J'ai essayé en mettant argb, abgr, bgra,
    voici le resultat :

    Nom : cpyBMPmethode2.png
Affichages : 180
Taille : 3,7 Ko

    Merci par avance pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Je ne comprend absolument pas ton souci , le titre est a mon avis un peu trompeur le bmp pour moi c'est un format image , et si ton .bmp est en RGB je vois pas pourquoi tu parle de 8 bits ?
    Mais d'un coter je ne vois aucun load de .bmp donc tu dois pas parler de ça j'imagine.

    Donc ton code ne fait pas du bmp 8bits , il fait ce qu'on appelle du 8 bpp (quand appelle bits par pixel) ou palette de couleurs en général pour du 8bpp.
    Le truc j'ai que j'ai deja modifiés la palette de couleurs et je n'ai jamais eu ce souci.
    Donc en fait tu modifie la palette de couleur mais quand tu fait SDL_CreateRGBSurface , en 8bpp deja créer t'il bien une palette de couleurs ? (on sait jamais ça peut être du 8bits RGB).

    Le probleme de ta copie c'est qu'il y a incompatibilité entre les format tu fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     for(j=0;j<spr->h;j++)
        for(i=0;i<spr->w;i++)            
          *(CpyPix+i+CpySpr->pitch*j) = *(Pix+i+spr->pitch*j);
    Deja je trouve cette boucle très moche , je comprend que t'as copié le code du code arkanoid , mais la pour une simple copie d'un tableau on peut faire beaucoup plus simple et lisible, de plus Pix je suis sur que c'est pas du 8bpp , mais plus du RGB et donc tu copie des données incompatibles , un l'octet représente un pixel qui pointe sur une palette ,et de l'autre sûrement du RGB 24 bits.
    Bref en gros tu ne fais aucune vérification.

    Après je pense que il y a beaucoup plus simple pour faire une copie d'une surface (un simple SDL_CreateRGBSurface/blit suffit) , mais je me pose la question si faire une copie d'une surface est réellement utile ?.
    Si tu veux économiser de la RAM , prend le format PCX , en général la SDL la chargera en 8bpp automatiquement.
    Si tu veux modifier la palette un simple changement de pointeur de la palette suffit la aussi.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 431
    Points : 172
    Points
    172
    Par défaut
    Merci pour ta réponse, en faite je sauvegarde en 256 couleurs sous paint.

    Mais d'un coter je ne vois aucun load de .bmp donc tu dois pas parler de ça j'imagine.
    Le load est fait dans cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int LoadBMP_spr(char* filename,init_sdl* J)
    {
      SDL_Surface* spr=NULL;
     
      if(!(malloc_error((spr=SDL_LoadBMP(filename)),"SDL_LoadBMP failed\n")))
      {
        FILE_ERROR;LINE_ERROR;
        return -1;
      }
      if(recovery_img(spr,J))
        return -1;
     
      return 0;
    }
    J'ai essayer de recopier mon sprite en faisant comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SDL_BlitSurface(spr,NULL,CpySpr,0);
    Mais cela ne fonctionne pas, effectivement cela doit venir du format créer par SDL_CreateRGBSurface.

    Pix je suis sur que c'est pas du 8bpp
    Pourtant j'ai tout casté en uint8

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     u8* CpyPix=(u8*)CpySpr->pixels;
     u8* Pix=(u8*)spr->pixels;

  4. #4
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Pourtant j'ai tout casté en uint8
    euh ça confirme que tu ne sais absolument pas ce que tu fait , tu cast les adresse en 8 bits , bien en quoi ça change le format ?
    De plus il faut lire une variable pour confirmé ou pas si c'est du 8bpp , et je le répète mais tu ne fait aucune vérification.

    Je repose mes questions , tu ne te rend pas compte mais je trouve que tu te casse la tête pour rien ,de plus ce que tu me demande n'est pas quelque chose que la SDL laisse 'facilement' modifier , dans le sens ou si tu veux modifier pixel par pixel ou la palette de couleur la il faut savoir ce qu'on fait.
    Et même si c'était le cas tu te casse la tete pour rien donc je répète mes question pourquoi tu veux faire cela ?
    Si tu veux économiser de la RAM , prend le format PCX , en général la SDL la chargera en 8bpp automatiquement.
    Si tu veux modifier la palette un simple changement de pointeur de la palette suffit la aussi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SDL_BlitSurface(spr,NULL,CpySpr,0);
    Alors je sais que src ->dst , en src 8bpp et dst 24 bits marche (en 16 bits ça devrait marcher aussi), je n'ai jamais testé 8bpp/ 8bpp , je ne sais pas si SDL_BlitSurface modifie la palette ou pas avec cette fonction.

    Donc pourquoi ne pas mettre CreateRGBSurface en 16 ou 24 bits ?
    A voir aussi dans la doc s'il il n'y a pas de fonction de copie de SDL_Surface.

    Bref en gros si tu ne comprend pas je que je t'ai dit (vu que tu me parle que en castant une adresse en change de format...) , fait du 24 bits pour tes image et ça marchera.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 431
    Points : 172
    Points
    172
    Par défaut
    De plus il faut lire une variable pour confirmé ou pas si c'est du 8bpp , et je le répète mais tu ne fait aucune vérification.
    OK je ferai comme tu dis.

    pourquoi tu veux faire cela ?
    En faite c'est quand je prends les coordonnées et dimension de mon image, ensuite j'efface l'image et je passe a la suivante, c'est pour ça.

    Voici la fonction qui prends les données de l'image :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
     
    #define ALPHA 253
    #define BACKROUND 252
     
    int recovery_img(SDL_Surface* spr,init_sdl* J)
    {
      int i,j,xi,yi;
      int nbImg=0;
      int PtRefX,PtRefY;
      int imgW,imgH;
      u8* pix=NULL;
      int xj,yj;
     
      if(save_spr(spr,J))
        return -1;
     
      pix=(u8*)spr->pixels;
     
      for(j=0;j<spr->h;j++) 
        for(i=0;i<spr->w;i++)
          {  	    
    	if(*(pix+i+spr->pitch*j)==ALPHA)
    	  {
    	    xi=i;
    	    yi=j;
    	    while(*(pix+xi+spr->pitch*yi)==ALPHA)
    	      imgW=xi++;
     
    	    while(*(pix+(xi-1)+spr->pitch*yi)==ALPHA)
    	      imgH=yi++;
     
    	    for(yi=j;yi<=imgH;yi++) 
    	      for(xi=i;xi<=imgW;xi++)
    		*(pix+xi+spr->pitch*yi)=BACKROUND;
     
    	    PtRefX=i+1;
    	    PtRefY=j+1;
    	    imgW=xi-PtRefX-1;
    	    imgH=yi-PtRefY-1;
    	  }
          }
      return 0;
    }
    Donc pourquoi ne pas mettre CreateRGBSurface en 16 ou 24 bits ?
    En faite je m'étais basé sur le jeux arkanoïd donc je voulais faire pareille que lui qui a codé son jeux en 8bits.

    Ps. :
    C'est bon j'ai pu trouver la solution (je n'y avais pas pensé) il fallait que je mette les valeurs des masks pour le 8bits/pixel

    voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int save_spr(SDL_Surface* spr,init_sdl* J)
    {
     int bpp = 8;
     u8 rmask = 0xE0;
     u8 gmask = 0x1C;
     u8 bmask = 0x3;
     u8 amask = 0;
     
    SDL_Surface* CpySpr = SDL_CreateRGBSurface(SDL_HWSURFACE,spr->w,spr->h,bpp,rmask,gmask,bmask,amask);
     
     SDL_BlitSurface(spr,NULL,CpySpr,0);
     SDL_BlitSurface(CpySpr,NULL,J->screen,0); /*C'est juste pour voir ci sa marche*/
     SDL_Flip(J->screen);
     
      return 0;
    }
    Merci pour ton aide cela ma permis de voir ou était le problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Enregistrement Image bmp 8bits
    Par garfieldlcht dans le forum VB.NET
    Réponses: 8
    Dernier message: 30/01/2014, 11h53
  2. Réponses: 5
    Dernier message: 15/01/2005, 18h29
  3. [BPW] Impression d'une image BMP
    Par Alcatîz dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 21/08/2003, 14h34
  4. Impression d'image bmp
    Par Invité dans le forum Langage
    Réponses: 6
    Dernier message: 18/07/2002, 09h38
  5. Création image BMP
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 16h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo