cfilergbbmp

Getting RGB values for each pixel from a 24bpp Bitmap for conversion to GBA format in C


I want to read the RGB values for each pixel from a .bmp file, so I can convert the bmp into a format suitable for GBA (GameBoy Advance).

I need to get just the RGB for each pixel and then write this information to a file.

I am trying to use the <windows.h> structures:

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;

but I only need RGB struct. So let's say I read "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);

Is this correct? How do I write only the RGB information to a file?


Solution

  • You need first to get the number of colors available in the embedded palette. This is available in the DIB Header.

    Then you can read all color components that contain the palette.

    You can see all header information like offset to know whereto seek : http://en.wikipedia.org/wiki/BMP_file_format.

    This should work: (Edit: Add code to write in file)

    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);