Search code examples
cbitmapstructurebitmapimage

Read bitmap file into structure


I would like to read a bitmap file into a struct and manipulate it like eg. making a mirror effect, but I cannot understand which kind of struct should I be creating in order to read into it.

Thank you for your help.


Solution

  • »This is how you manually load a .BMP file

    The bitmap file format:

    • Bitmap file header
    • Bitmap info header
    • Palette data
    • Bitmap data

    So on with the code part. This is our struct we need to create to hold the bitmap file header.

    #pragma pack(push, 1)
    
    typedef struct tagBITMAPFILEHEADER
    {
        WORD bfType;  //specifies the file type
        DWORD bfSize;  //specifies the size in bytes of the bitmap file
        WORD bfReserved1;  //reserved; must be 0
        WORD bfReserved2;  //reserved; must be 0
        DWORD bfOffBits;  //specifies the offset in bytes from the bitmapfileheader to the bitmap bits
    }BITMAPFILEHEADER;
    
    #pragma pack(pop)
    

    The bftype field checks to see if you are in fact loading a .BMP file, and if you are, the field should be 0x4D42.

    Now we need to create our bitmapinfoheader struct. This holds info about our bitmap.

    #pragma pack(push, 1)
    
    typedef struct tagBITMAPINFOHEADER
    {
        DWORD biSize;  //specifies the number of bytes required by the struct
        LONG biWidth;  //specifies width in pixels
        LONG biHeight;  //specifies height in pixels
        WORD biPlanes;  //specifies the number of color planes, must be 1
        WORD biBitCount;  //specifies the number of bits per pixel
        DWORD biCompression;  //specifies the type of compression
        DWORD biSizeImage;  //size of image in bytes
        LONG biXPelsPerMeter;  //number of pixels per meter in x axis
        LONG biYPelsPerMeter;  //number of pixels per meter in y axis
        DWORD biClrUsed;  //number of colors used by the bitmap
        DWORD biClrImportant;  //number of colors that are important
    }BITMAPINFOHEADER;
    
    #pragma pack(pop)
    

    Now on to loading our bitmap.

    unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
    {
        FILE *filePtr;  //our file pointer
        BITMAPFILEHEADER bitmapFileHeader;  //our bitmap file header
        unsigned char *bitmapImage;  //store image data
        int imageIdx=0;  //image index counter
        unsigned char tempRGB;  //our swap variable
    
        //open file in read binary mode
        filePtr = fopen(filename,"rb");
        if (filePtr == NULL)
            return NULL;
    
        //read the bitmap file header
        fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER),1,filePtr);
    
        //verify that this is a .BMP file by checking bitmap id
        if (bitmapFileHeader.bfType !=0x4D42)
        {
            fclose(filePtr);
            return NULL;
        }
    
        //read the bitmap info header
        fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER),1,filePtr); 
    
        //move file pointer to the beginning of bitmap data
        fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
    
        //allocate enough memory for the bitmap image data
        bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage);
    
        //verify memory allocation
        if (!bitmapImage)
        {
            free(bitmapImage);
            fclose(filePtr);
            return NULL;
        }
    
        //read in the bitmap image data
        fread(bitmapImage,bitmapInfoHeader->biSizeImage,1,filePtr);
    
        //make sure bitmap image data was read
        if (bitmapImage == NULL)
        {
            fclose(filePtr);
            return NULL;
        }
    
        //swap the R and B values to get RGB (bitmap is BGR)
        for (imageIdx = 0;imageIdx < bitmapInfoHeader->biSizeImage;imageIdx+=3)
        {
            tempRGB = bitmapImage[imageIdx];
            bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
            bitmapImage[imageIdx + 2] = tempRGB;
        }
    
        //close file and return bitmap image data
        fclose(filePtr);
        return bitmapImage;
    }
    

    Now to make use of all of this:

    BITMAPINFOHEADER bitmapInfoHeader;
    unsigned char *bitmapData;
    // ...
    bitmapData = LoadBitmapFile("mypic.bmp",&bitmapInfoHeader);
    //now do what you want with it, later on I will show you how to display it in a normal window
    

    Later on I'll put up Writing to a .BMP, and how to load a targa file, and how to display them.«

    Quoted from: http://www.vbforums.com/showthread.php?261522-C-C-Loading-Bitmap-Files-%28Manually%29 (User: BeholderOf). (Some minor corrections done)