Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 785
Ege Avatar asked Jan 11 '13 13:01

Ege


People also ask

How do I read a BMP file?

You can open BMP files on either PC or Mac with external software, such as Adobe Creative Cloud. If you use a PC or Mac, start by opening the folder with the BMP file you want to use. Right-click on the file name and then hover over the Open With option.

How do I read a bitmap image in Python?

For reading, the open() function accepts a filename(string), a path object or an image(file) object. So, by using the open() function, we are actually reading the image. Image. open() will read the image and get all the relevant information from the image.

What is BMP file used for?

BMP is a simple raster graphics image file format designed to store bitmap digital images independently of a display device, originally and primarily on Microsoft Windows and OS/2 operating systems.


Video Answer


2 Answers

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

like image 138
ollo Avatar answered Sep 22 '22 13:09

ollo


here A short working example.

It converts a wav-file to bmp (a long ago I had such fun).

Code:

#include <stdio.h> #include <strings.h> #include <sndfile.h> #include <stdlib.h> #include <math.h>  #define RATE 44100  typedef struct {     unsigned short type;                 /* Magic identifier            */     unsigned int size;                       /* File size in bytes          */     unsigned int reserved;     unsigned int offset;                     /* Offset to image data, bytes */ } HEADER; typedef struct {     unsigned int size;               /* Header size in bytes      */     int width,height;                /* Width and height of image */     unsigned short planes;       /* Number of colour planes   */     unsigned short bits;         /* Bits per pixel            */     unsigned int compression;        /* Compression type          */     unsigned int imagesize;          /* Image size in bytes       */     int xresolution,yresolution;     /* Pixels per meter          */     unsigned int ncolours;           /* Number of colours         */     unsigned int importantcolours;   /* Important colours         */ } INFOHEADER; typedef struct {     unsigned char r,g,b,junk; } COLOURINDEX;   int main(int argc, char *argv[]){     int i,j,rd;     int gotindex = 0;     unsigned char grey,r,g,b;     double ampl;     short _2byte[2];     HEADER header;     INFOHEADER infoheader;     COLOURINDEX colourindex[256];     FILE *fptr;      SNDFILE* sndfile = NULL;     SF_INFO sfinfo;     long rate = RATE;      void (*bmpread)();     void _eightbit(){         if(fread(&grey, sizeof(unsigned char), 1, fptr) != 1){         fprintf(stderr,"Image read failed\n");         exit(-1);         }         if (gotindex){             ampl =  colourindex[grey].r * 64. +                 colourindex[grey].g * 128.+                 colourindex[grey].b * 64.;         } else {             ampl = grey * 256. - 32768.;         } //      printf("%.2f\n", ampl);     }     void _twentyfourbit(){         do{             if((rd = fread(&b, sizeof(unsigned char), 1, fptr)) != 1) break;             if((rd = fread(&g, sizeof(unsigned char), 1, fptr)) != 1) break;             if((rd = fread(&r, sizeof(unsigned char), 1, fptr)) != 1) break;         }while(0);         if(rd != 1){                 fprintf(stderr,"Image read failed\n");             exit(-1);         }         ampl = r * 64. + g * 128. + b * 64. - 32768.; //      printf("%.2f\n", ampl);     }     if (argc < 3){         printf("Usage: %s <input.bmp> <output.wav> [samplerate]\n", argv[0]);         printf("For example:\n\t%s pict.bmp sample.wav 44100 2\n", argv[0]);         exit(0);     }     printf("Input file: %s\n", argv[1]);     printf("Output file: %s\n", argv[2]);     if(argc > 3) rate = atoi(argv[3]);     if(rate < 4000) rate = 4000;     //if(argc > 4) channels = atoi(argv[4]);             sfinfo.samplerate = rate;     sfinfo.channels = 2;     sfinfo.format = SF_FORMAT_WAV|SF_FORMAT_PCM_16;     if((fptr = fopen(argv[1],"r")) == NULL) {         fprintf(stderr,"Unable to open BMP file \"%s\"\n",argv[1]);         exit(-1);     }         /* Read and check BMP header */     if(fread(&header.type, 2, 1, fptr) != 1){         fprintf(stderr, "Failed to read BMP header\n");         exit(-1);     }     if(header.type != 'M'*256+'B'){         fprintf(stderr, "File is not bmp type\n");         exit(-1);     }     do{         if((rd = fread(&header.size, 4, 1, fptr)) != 1) break;         printf("File size: %d bytes\n", header.size);         if((rd = fread(&header.reserved, 4, 1, fptr)) != 1) break;         if((rd = fread(&header.offset, 4, 1, fptr)) != 1) break;         printf("Offset to image data is %d bytes\n", header.offset);     }while(0);     if(rd =! 1){         fprintf(stderr, "Error reading file\n");         exit(-1);     }     /* Read and check the information header */     if (fread(&infoheader, sizeof(INFOHEADER), 1, fptr) != 1) {         fprintf(stderr,"Failed to read BMP info header\n");         exit(-1);     }     printf("Image size = %d x %d\n", infoheader.width, infoheader.height);     printf("Number of colour planes is %d\n", infoheader.planes);     printf("Bits per pixel is %d\n", infoheader.bits);     printf("Compression type is %d\n", infoheader.compression);     printf("Number of colours is %d\n", infoheader.ncolours);     printf("Number of required colours is %d\n", infoheader.importantcolours);     /* Read the lookup table if there is one */     for (i=0; i<255; i++){         colourindex[i].r = rand() % 256;         colourindex[i].g = rand() % 256;         colourindex[i].b = rand() % 256;         colourindex[i].junk = rand() % 256;     }     if (infoheader.ncolours > 0) {         for (i=0; i<infoheader.ncolours; i++){             do{             if ((rd = fread(&colourindex[i].b, sizeof(unsigned char),1,fptr)) != 1)                 break;             if ((rd = fread(&colourindex[i].g, sizeof(unsigned char),1,fptr)) != 1)                 break;             if ((rd = fread(&colourindex[i].r, sizeof(unsigned char),1,fptr)) != 1)                 break;             if ((rd = fread(&colourindex[i].junk, sizeof(unsigned char),1,fptr)) != 1)                 break;             }while(0);             if(rd != 1){                 fprintf(stderr,"Image read failed\n");                 exit(-1);             }                        printf("%3d\t%3d\t%3d\t%3d\n", i,             colourindex[i].r, colourindex[i].g, colourindex[i].b);         }         gotindex = 1;     }     if(infoheader.bits < 8){         printf("Too small image map depth (%d < 8)\n", infoheader.bits);         exit(-1);     }     /* Seek to the start of the image data */     fseek(fptr, header.offset, SEEK_SET);     printf("Creating 16bit WAV %liHz.\n", rate);     sndfile = sf_open(argv[2], SFM_WRITE, &sfinfo);     if(sndfile == NULL){         fprintf(stderr, "Cannot open output file!\n"); exit(-1);     }     bmpread = _eightbit;     if(infoheader.bits == 24)         bmpread = _twentyfourbit;      /* Read the image */     for (j=0;j<infoheader.height;j++) {         _2byte[1] = 32700;         for (i=0;i<infoheader.width;i++) {             bmpread();             _2byte[0] = (short)ampl;             sf_write_short(sndfile, _2byte, 2);             _2byte[1] = 0;         } // i     } // j     fclose(fptr);     sf_close(sndfile); } 
like image 21
Eddy_Em Avatar answered Sep 19 '22 13:09

Eddy_Em