Obtenir les valeurs RVB pour chaque pixel d'une Bitmap 24bpp pour la conversion au format GBA en C

StackOverflow https://stackoverflow.com/questions/1531268

  •  20-09-2019
  •  | 
  •  

Question

Je veux lire les valeurs RVB pour chaque pixel à partir d'un fichier .bmp, donc je peux convertir le bmp en un format adapté à l'ACS (GameBoy Advance).

Je dois obtenir juste le RVB pour chaque pixel, puis écrire ces informations dans un fichier.

Je suis en train d'utiliser les structures de <windows.h>:

typedef struct
{
    char signature[2];
    unsigned int fileSize;
    unsigned int reserved;
    unsigned int offset;
}BmpHeader;

typedef struct
{
    unsigned int headerSize;
    unsigned int width;
    unsigned int height;
    unsigned short planeCount;
    unsigned short bitDepth;
    unsigned int compression;
    unsigned int compressedImageSize;
    unsigned int horizontalResolution;
    unsigned int verticalResolution;
    unsigned int numColors;
    unsigned int importantColors;

}BmpImageInfo;

typedef struct
{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    unsigned char reserved;
}Rgb;

typedef struct
{
    BmpHeader header;
    BmpImageInfo info;
    Rgb colors[256];
    unsigned short image[1];
}BmpFile;

mais je ne ai besoin struct RVB. Alors disons que je lis « in.bmp »:

FILE *inFile, *outFile;
inFile = fopen("C://in.bmp", "rb");

Rgb Palette[256];
for(i=0;i<256;i++)
{
   fread(&Palette[i],sizeof(Rgb),1,inFile);
}

fclose(inFile);

Est-ce exact? Comment puis-je écrire que les informations RVB dans un fichier?

Était-ce utile?

La solution

Vous devez d'abord obtenir le nombre de couleurs disponibles dans la palette intégrée. Il est disponible dans l'en-tête DIB.

Ensuite, vous pouvez lire tous les composants de couleur qui contiennent la palette.

Vous pouvez voir toutes les informations d'en-tête offset savoir vers quoi chercher: http: //en.wikipedia. org / wiki / BMP_file_format .

Cela devrait fonctionner: (Edit: Ajouter du code à écrire dans le fichier)

FILE *inFile, *outFile;
BMPHeader header;
BMPImageInfo info;
RGB *palette, *p;
int i = 0;

inFile = fopen("C://in.bmp", "rb");
if( !inFile )
   return;

if( fread(&header, sizeof(BMPHeader), 1, inFile) != 1 )
   return; // Manage error and close file

if( fread&info, sizeof(BMPImageInfo), 1, inFile) != 1 )
   return; // Manage error and close file

if( info.numColors > 0 )
{
   palette = (RGB*)malloc(sizeof(RGB) * info.numColors);
   if( fread(palette, sizeof(RGB), info.numColors, inFile) != info.numColors )
      return; // manage error and close file
}

fclose(inFile)

// Binary method => if read later by another computer
outFile = fopen("path", "wb");
if( !outFile )
   return;

if( fwrite(&info.numColors, sizeof(unsigned int), 1, outFile) != 1 )
   return; // Manage Error and close file

if( fwrite(&palette, sizeof(RGB), info.numColors, outFile) != info.numColors )
   return; // Manage error and close file

fclose(outFile);

// Text method => if read later by human
outFile = fopen("path", "w");
if( !outFile )
   return;

for( i=0; i<info.numColors; ++i )
{
   p = &palette[i];
   if( fprintf(outFile, "R:%d, G:%d, B:%d\n", p->red, p->green, p->blue) < 0 )
      return; // Manage error and close file
}

fclose(outFile);

Autres conseils

Je l'ai fait un peu d'essais et a étendu le programme de Patrice un peu. Je ne suis pas un bon programmeur C, donc tout le crédit va à lui et mes pièces ne sont pas aussi élégant que son -. Désolé

Attention:. Énorme code source avant

#include <stdio.h>
#pragma pack(2)


typedef struct
{
    char signature[2];
    unsigned int fileSize;
    unsigned int reserved;
    unsigned int offset;
} BmpHeader;

typedef struct
{
    unsigned int headerSize;
    unsigned int width;
    unsigned int height;
    unsigned short planeCount;
    unsigned short bitDepth;
    unsigned int compression;
    unsigned int compressedImageSize;
    unsigned int horizontalResolution;
    unsigned int verticalResolution;
    unsigned int numColors;
    unsigned int importantColors;

} BmpImageInfo;

typedef struct
{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    //unsigned char reserved; Removed for convenience in fread; info.bitDepth/8 doesn't seem to work for some reason
} Rgb;


int main( int argc, char **argv ) {

    FILE *inFile;
    BmpHeader header;
    BmpImageInfo info;
    Rgb *palette;
    int i = 0;

    printf( "Opening file %s for reading.\n", argv[1] );

    inFile = fopen( argv[1], "rb" );
    if( !inFile ) {
        printf( "Error opening file %s.\n", argv[1] );
        return -1;
    }

    if( fread(&header, 1, sizeof(BmpHeader), inFile) != sizeof(BmpHeader) ) {
        printf( "Error reading bmp header.\n" );
        return -1;
    }

    if( fread(&info, 1, sizeof(BmpImageInfo), inFile) != sizeof(BmpImageInfo) ) {
        printf( "Error reading image info.\n" );
        return -1;
    }

    if( info.numColors > 0 ) {
        printf( "Reading palette.\n" );
        palette = (Rgb*)malloc(sizeof(Rgb) * info.numColors);
        if( fread(palette, sizeof(Rgb), info.numColors, inFile) != (info.numColors * sizeof(Rgb)) ) {
            printf( "Error reading palette.\n" );
            return -1; // error
        }
    }

    printf( "Opening file %s for writing.\n", argv[2] );
    FILE *outFile = fopen( argv[2], "wb" );
    if( !outFile ) {
        printf( "Error opening outputfile.\n" );
        return -1;
    }
    Rgb *pixel = (Rgb*) malloc( sizeof(Rgb) );
    int read, j;
    for( j=0; j<info.height; j++ ) {
        printf( "------ Row %d\n", j+1 );
        read = 0;
        for( i=0; i<info.width; i++ ) {
            if( fread(pixel, 1, sizeof(Rgb), inFile) != sizeof(Rgb) ) {
                printf( "Error reading pixel!\n" );
                return -1;
            }
            read += sizeof(Rgb);
            printf( "Pixel %d: %3d %3d %3d\n", i+1, pixel->red, pixel->green, pixel->blue );
        }
        if( read % 4 != 0 ) {
            read = 4 - (read%4);
            printf( "Padding: %d bytes\n", read );
            fread( pixel, read, 1, inFile );
        }
    }

    printf( "Done.\n" );
    fclose(inFile);
    fclose(outFile);

    printf( "\nBMP-Info:\n" );
    printf( "Width x Height: %i x %i\n", info.width, info.height );
    printf( "Depth: %i\n", (int)info.bitDepth );

    return 0;

}

Ce programme lit les informations de pixel stockées dans le fichier. Il faut le rembourrage en compte, mais ne fonctionne qu'avec bmps avec 24 bits par la profondeur de couleur de pixel (Si vous avez besoin d'autres profondeurs, vous devrez personnaliser le struct Rgb). Espérons que cela vous aide, mais comme je l'ai dit, il est juste une extension du code de Patrice.

Voici un exemple de sortie de mon testfile:

$ ./a.out test.bmp out.txt
Opening file test.bmp for reading.
Opening file out.txt for writing.
------ Row 1
Pixel 1:   0   0   0
Pixel 2:   0   0   0
Pixel 3:   0   0   0
Pixel 4:   0   0   0
Pixel 5:   0   0   0
Padding: 1 bytes
------ Row 2
Pixel 1:   0   0   0
Pixel 2: 232  33  33
Pixel 3:   0   0   0
Pixel 4: 232  33  33
Pixel 5:   0   0   0
Padding: 1 bytes
------ Row 3
Pixel 1:   0   0   0
Pixel 2:   0   0   0
Pixel 3: 232  33  33
Pixel 4:   0   0   0
Pixel 5:   0   0   0
Padding: 1 bytes
------ Row 4
Pixel 1:   0   0   0
Pixel 2: 232  33  33
Pixel 3:   0   0   0
Pixel 4: 232  33  33
Pixel 5:   0   0   0
Padding: 1 bytes
------ Row 5
Pixel 1:   0   0   0
Pixel 2:   0   0   0
Pixel 3:   0   0   0
Pixel 4:   0   0   0
Pixel 5:   0   0   0
Padding: 1 bytes
Done.

BMP-Info:
Width x Height: 5 x 5
Depth: 24

Edit: Oui, mon image affiche une croix rouge. Notez que l'image est stockée à l'envers si la ligne 1 du fichier est rangée en fait 5 de l'image. D'oh a oublié d'écrire quelque chose pour déposer le code ouvre, mais cela reste comme excercise à vous;)

.

Voir la page wikipedia de .bmp format de fichier qui fournit beaucoup d'informations sur la structure du fichier et devrait vous aider à analyser.

http://en.wikipedia.org/wiki/BMP_file_format

Dans votre code, vous devez d'abord lire l'adresse de départ des données (spécifié dans la tête de fichier) et la hauteur de l'image. Ensuite, chercher à ce poste. Après que vous avez lu dans un pixel de ligne par pixel (l'en-tête indique le nombre de bits par pixel) et doivent prendre soin du rembourrage 32 bits à la fin de celui-ci. On notera que dans une image de 24 bits (RGB) les informations sont stockées dans l'ordre BGR. Aussi, si la valeur de hauteur ne soit pas négatif, l'image est stockée à l'envers.

Je ne suis pas familier avec le format de fichier BMP, mais ne vous devez lire les informations d'en-tête en premier? Quelque chose comme:

BmpHeader header;
fread(&header,sizeof(BmpHeader),1,inFile);

et lire des informations détaillées sur l'image, que vous aurez besoin:

BmpImageInfo info;
fread(&info,sizeof(BmpImageInfo),1,inFile);

et lire les informations de la palette ainsi.

une fois que vous avez que vous connaîtrez la taille du fichier et des données de décalage. Vous pouvez pré-allouer suffisamment d'espace et lire tout à la fois, ce qui peut être plus simple. Sinon, vous pouvez lire en morceaux et analyser comme vous allez (réduit la chance de ne pas avoir assez de mémoire, mais l'analyse est plus complexe).

Vous saurez également de la section d'information si la compression est activée, les dimensions des images etc.

Si vous lisez tout à la fois, sauter au décalage des données, et faire quelque chose comme:

Rgb* rgb = offset;
blueVal = rgb->blue;
greenVal = rgb->green;
redVal = rgb->red;
rgb += sizeof( Rgb );

et ainsi de suite. Il est évident que le code ne vérifie pas pour les erreurs, à la fin de tampon, et ainsi de suite, vous aurez donc besoin de le faire. Vous aurez probablement aussi de lire des informations de la palette pour donner un sens des données d'image.

Ou, comme quelqu'un l'a dit, regardez la spécification de format sur Wikipédia

Si le fichier BMP a une palette puis le code ci-dessous devrait travail:

  FILE *inFile, *outFile;
  inFile = fopen("C:/in.bmp", "rb");
  Rgb Palette[256];
  if ( inFile ) {
    // Bypass headers
    fseek(inFile, sizeof(BmpHeader) + sizeof(BmpImageInfo), SEEK_SET);
    // Load the whole palette
    fread(Palette, sizeof(Palette), 1, inFile);
    fclose(inFile);
  }

Vous trouverez peut-être utile de regarder un peu de code C je l'ai écrit il y a plusieurs années pour la lecture et l'écriture de fichiers BMP, situés à:

http://david.tribble.com/src/bmp/bmp.html

Je crois qu'il gère les différentes tailles de bits de pixels (1/2/4/8/24) ainsi que la compression RLE.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top