Lecture d’un fichier BMP 24 bits

0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

Le fichier entête “d’entrées/sorties” qui va nous permettre de manipuler les fichiers :

#include 

Ensuite la définition d’un “macro” qui simplifie la convertion en ‘int’ :

#define CTOI(C) (*(int*)&C) 

La structure qui va acceuillir les données de notre image :

// la structure qui contient les infos de notre image
struct PropPicture {

    // l'entête
    unsigned char   Header[0x36];

    // la position et la taille des données
    unsigned int    DataPos, DataSize;

    // les dimensions de l'image
    int     Width, Height;

    // le nombre de composants (en général 3 : rgb)
    int    Components;

    // les données
    unsigned char   *Data;

};

Cette fonction va nous permettre de charger les données d’un bmp dans notre structure de type “PropPicture”:

// charge une texture de type BMP
int LoadTextureBMP( struct PropPicture &prop_sz , char * fichier_sz)
{

    // on déclare la variable qui va nous permettre de manipuler notre fichier
    FILE * fichier;

    // on ouvre le fichier
    fichier = fopen( fichier_sz,"rb" );

    // on vérifie qu'il est bien ouvert
    if ( !fichier )
        return FALSE; // non, on quitte la fonction

    // on charge l'entête (54 octets) et on vérifie que les infos qui s'y trouvent sont correctes
    if ( fread(prop_sz.Header,1,0x36,fichier) != 0x36 )
        return FALSE;

    if ( prop_sz.Header[0]!= 'B' || prop_sz.Header[1] != 'M' )
        return FALSE;

    if ( CTOI(prop_sz.Header[0x1E]) != 0 )
        return FALSE;

    if ( CTOI(prop_sz.Header[0x1C]) != 24 )
        return FALSE;

    // on récupère les infos de l'entête
    prop_sz.DataPos = CTOI( prop_sz.Header[0x0A] );
    prop_sz.DataSize = CTOI( prop_sz.Header[0x22] );

    // on récupère les infos de l'image
    prop_sz.Width = CTOI( prop_sz.Header[0x12] );
    prop_sz.Height = CTOI( prop_sz.Header[0x16] );

    // on définit le nombre de composants
    // on ne charge ici que des images ayant 3 composants (rgb)
    prop_sz.Components = 3;

    // si on a pas réussi à récupèrer la taille des données, on la calcule
    if( prop_sz.DataSize==0 )
        prop_sz.DataSize = prop_sz.Width * prop_sz.Height * prop_sz.Components;

    // même chose ici, si on a pas réussi à récupèrer la position des données, on spécifie celle par défaut
    if( prop_sz.DataPos==0 )
        prop_sz.DataPos = 0x36;

    // on charge l'image
    fseek(fichier,prop_sz.DataPos,0);

    // on alloue un espace suffisant pour stocker les données
    prop_sz.Data = new unsigned char[prop_sz.DataSize];

    // on vérifie que l'allocation s'est bien passée
    if( !prop_sz.Data )
        return FALSE;

    // on lit les données
    if( fread(prop_sz.Data,1,prop_sz.DataSize,fichier) != prop_sz.DataSize )
    {
        // il y a eu une erreur, on désalloue la mémoire
        delete prop_sz.Data;

        // on ferme le fichier
        fclose(fichier);

        // et on quitte la fonction
        return FALSE;
    }

    // on a bien récupéré les données...
    // on ferme le fichier
    fclose(fichier);

    // inverse R et B
    // dans un fichier bmp, les couleurs sont enregistrées dans cet ordre : bgr
    // on les remets dans le 'bon' ordre (rgb)
    unsigned char t;

    for( int x=0; x<(prop_sz.Width * prop_sz.Height) ; x++ )
    {
        t = prop_sz.Data[x*3];
        prop_sz.Data[x*3] = prop_sz.Data[x*3+2];
        prop_sz.Data[x*3+2] = t;
    }

    // on retourne TRUE si tout s'est bien passé
    return TRUE;

}

Pour utiliser ce code:

// on définit une nouvelle structure
PropPicture test;

// et on appelle notre fonction en passant notre structure ainsi que le nom du fichier à charger
LoadTextureBMP( test , "nuage1.bmp" )
0 Flares Twitter 0 Facebook 0 Google+ 0 Email -- Filament.io 0 Flares ×

Leave a Comment

*