BMP Reader in C++
Posted: Tue Sep 22, 2009 11:54 pm
- The first thing you should always do when handling a program that uses Windows is to include the windows.h header.
Code: Select all
#include <windows.h>
- Header structure 1
bfTypeCode: Select all
typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *PBITMAPFILEHEADER;
Specifies the file type. It must be set to the signature word BM (0x4D42) to indicate bitmap.
bfSize
Specifies the size, in bytes, of the bitmap file.
For a 24-bit file, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * Width * Height
bfReserved1
Reserved; set to zero
bfReserved2
Reserved; set to zero
bfOffBits
Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits.
i.e.: sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) - Header structure 2
biSizeCode: Select all
typedef struct tagBITMAPINFOHEADER { DWORD biSize; // size of structure, in bytes DWORD biWidth; // bitmap width, in pixels DWORD biHeight; // bitmap height, in pixels WORD biPlanes; // see below WORD biBitCount; // see below DWORD biCompression; // see below DWORD biSizeImage; // see below DWORD biXPelsPerMeter; // see below DWORD biYPelsPerMeter; // see below DWORD biClrUsed; // see below DWORD biClrImportant; // see below } BITMAPINFOHEADER;
Specifies the size of the structure, in bytes.
biWidth
Specifies the width of the bitmap, in pixels.
biHeight
Specifies the height of the bitmap, in pixels.
biPlanes
Specifies the number of planes for the target device.
This value must be set to 1.
biBitCount
Specifies the number of bits per pixel.
biCompression
Specifies the type of compression for a compressed bottom-up bitmap. Use BI_RGB for an uncompressed format.
biSizeImage
Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.
biXPelsPerMeter
Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap. Set this to 2400.
biYPelsPerMeter
Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap. Set this to 2400.
biClrUsed
Specifies the number of color indexes in the color table that are actually used by the bitmap. Set this to 0.
biClrImportant
Specifies the number of color indexes required for displaying the bitmap. If this value is zero, all colors are required. - Image itself is an array of RGBTRIPLES. Sometimes padding is required, but we shouldn't encounter that problem with bitmaps that have a width as a multiple of 4.
For a 128 * 128 pixel image, this would be declared as:Code: Select all
RGBTRIPLE image[128*128];
- Simple example
Code: Select all
#include <windows.h> #include <iostream.h> HANDLE hfile; DWORD written; BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; RGBTRIPLE *image; void() { // Open the file hfile = CreateFile("source.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL); // Read the header ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL); ReadFile(hfile,&bih,sizeof(bih),&written,NULL); // Read image imagesize = bih.biWidth*bih.biHeight; // Helps you allocate memory for the image image = new RGBTRIPLE[imagesize]; // Create a new image (I'm creating an array during runtime) ReadFile(hfile,image,imagesize*sizeof(RGBTRIPLE),&written,NULL); // Reads it off the disk // Close source file CloseHandle(hfile); // Now for some information cout<<"The image width is "<<bih.biWidth<<"\n"; // Will output the width of the bitmap cout<<"The image height is "<<bih.biHeight<<"\n"; // Will output the height of the bitmap }
- Since the BMP image is kept upside down in the file, we need to use following codes to read/write pixels.
Code: Select all
RGBTRIPLE get_pixel(int x,int y) { // Image define from earlier return image[(bih.biHeight-1-y)*bih.biWidth+x]; } RGBTRIPLE set_pixel(int x,int y,RGBTRIPLE color) { // Image define from earlier image[(bih.biHeight-1-y)*bih.biWidth+x] = color; }