Directory of Audio and Video Introduction Articles
BMP file format parsing
BMP file is composed of four parts: file header, bitmap information header, color information and graphics data.
Bitmap file header (14 bytes) | Bitmap header (40 bytes) | Color information | graphic data |
---|
- The total number of file headers and information headers is 54 bytes.
- RGB data section:
RGB24 files are stored in the order of RGB, RGB, RGB... RGB
BMP file RGB data storage order is BGR, BGR, BGR... BGR
bitmap-file header
Bitmap file header is divided into four parts, a total of 14 bytes
Name | Occupancy space | content | Example data |
---|---|---|---|
bfType | 2 byte | The logo is "BM" | BM |
bfSize | 4 byte | Size of the whole BMP file | 0x000C0036(786486) |
bfReserved1 | 2 byte | Reserved word | 0 |
bfReserved2 | 2 byte | Reserved word | 0 |
bfOffBits | 4 byte | Offset number, that is, the size of bitmap file header + bitmap information header + palette | 0x36(54) |
Bitmap header
Bitmap headers total 40 bytes
Name | Occupancy space | content | Example data |
---|---|---|---|
biSize | 4 byte | The size of the bitmap header is 40 | 0x28(40) |
biWidth | 4 byte | Bitmap width, in pixels | 0x200(512) |
biHeight | 4 byte | The height of a bitmap in pixels | 0x200(512) |
biPlanes | 2 byte | Fixed value 1 | 1 |
biBitCount | 2 byte | Bits per pixel 1-black-and-white, 4-16, 8-256, 24-true, 32-with alpha channels | 0x18(24) |
biCompression | 4 byte | Compression mode, BI_RGB(0) is uncompressed | 0 |
biSizeImage | 4 byte | The number of bytes occupied by all the bitmap pixels, BI_RGB can be set to 0. | 0x0C |
biXPelsPerMeter | 4 byte | Horizontal Resolution (Pixel/m) | 0 |
biYPelsPerMeter | 4 byte | Vertical Resolution (Pixel/m) | 0 |
biClrUsed | 4 byte | If the number of colors used by the bitmap is 0, then the biBitCount power of the number of colors is 2 | 0 |
biClrImportant | 4 byte | Important number of colours, 0 represents all colours are important | 0 |
Converting RGB24 Pixel Point Data into BMP Format Pictures
Conversion code:
#include <stdio.h> #include <stdlib.h> // Seven Colors of Rainbow u_int32_t rainbowColors[] = { 0XFF0000, // red 0XFFA500, // orange 0XFFFF00, // yellow 0X00FF00, // green 0X007FFF, // young 0X0000FF, // blue 0X8B00FF // purple }; /*bmp file header*/ typedef struct { unsigned int bfSize; /* Size of file */ unsigned short bfReserved1; /* Reserved */ unsigned short bfReserved2; /* ... */ unsigned int bfOffBits; /* Offset to bitmap data */ } BitmapFileHeader; /*bmp info header*/ typedef struct { unsigned int biSize; /* Size of info header */ int biWidth; /* Width of image */ int biHeight; /* Height of image */ unsigned short biPlanes; /* Number of color planes */ unsigned short biBitCount; /* Number of bits per pixel */ unsigned int biCompression; /* Type of compression to use */ unsigned int biSizeImage; /* Size of image data */ int biXPelsPerMeter; /* X pixels per meter */ int biYPelsPerMeter; /* Y pixels per meter */ unsigned int biClrUsed; /* Number of colors used */ unsigned int biClrImportant; /* Number of important colors */ } BitmapInfoHeader; void writeRGBToBmp(char *filename, int width, int height) { FILE *bitmapFile = fopen(filename, "wb"); if(!bitmapFile) { printf("Could not write file \n"); return; } uint16_t bfType = 0x4d42; BitmapFileHeader fileHeader; fileHeader.bfReserved1 = 0; fileHeader.bfReserved2 = 0; fileHeader.bfSize = 2 + sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + width*height*3; fileHeader.bfOffBits = 0x36; BitmapInfoHeader infoHeader; infoHeader.biSize = sizeof(BitmapInfoHeader); infoHeader.biWidth = width; infoHeader.biHeight = height; infoHeader.biPlanes = 1; infoHeader.biBitCount = 24; infoHeader.biSizeImage = 0; infoHeader.biCompression = 0; infoHeader.biXPelsPerMeter = 5000; infoHeader.biYPelsPerMeter = 5000; infoHeader.biClrUsed = 0; infoHeader.biClrImportant = 0; fwrite(&bfType, sizeof(bfType), 1, bitmapFile); fwrite(&fileHeader, sizeof(fileHeader), 1, bitmapFile); fwrite(&infoHeader, sizeof(infoHeader), 1, bitmapFile); // Write image data for (int i = 0; i < width; ++i) { // Current color u_int32_t currentColor = rainbowColors[0]; if(i < 100) { currentColor = rainbowColors[0]; } else if(i < 200) { currentColor = rainbowColors[1]; } else if(i < 300) { currentColor = rainbowColors[2]; } else if(i < 400) { currentColor = rainbowColors[3]; } else if(i < 500) { currentColor = rainbowColors[4]; } else if(i < 600) { currentColor = rainbowColors[5]; } else if(i < 700) { currentColor = rainbowColors[6]; } // Current color R component u_int8_t R = (currentColor & 0xFF0000) >> 16; // Current color G component u_int8_t G = (currentColor & 0x00FF00) >> 8; // Current color B component u_int8_t B = currentColor & 0x0000FF; for (int j = 0; j < height; ++j) { // Write a pixel RGB24 to a file in BGR order fwrite(&B, 1, 1, bitmapFile); fwrite(&G, 1, 1, bitmapFile); fwrite(&R, 1, 1, bitmapFile); } } // Close file fclose(bitmapFile); } int main() { writeRGBToBmp("/Users/staff/Desktop/rainbow-700x700.bmp", 700, 700); return 0; }
Check the generated BMP image
Congratulations! The picture viewing software recognizes our BMP picture, and the preview is normal!
BUT! What seems to be wrong?! Our rainbow is upside down!
Rainbow color, from top to bottom should be:
Red - > Orange - > Yellow - > Green - > Green - > Blue - > Purple
This picture is:
Purple - > Blue - > Green - > Green - > Yellow - > Orange - > Red
Handling picture inversion
The biHeight field in BitmapInfoHeader,
Bitmaps are scanned from bottom to top.
The biHeight is negative and the bitmap is scanned from top to bottom.
If the setting of this value does not match the scanning mode of the original bitmap file, the image display may be reversed.
<br/>
In the transformation code above, the BitmapInfoHeader section:
// infoHeader.biHeight = height; infoHeader.biHeight = -height;
Congratulations!
Successful use of pixels to spell out a "real" picture!
Code:
Reference material:
Bitmap (bmp) file format analysis
Converting RGB24 into BMP Image
Differences between RGB32 and RGB24
non-dword-aligned-pixel-to-dword-aligned-bitmap
generate-bmp-file-from-array-of-rgb-values
Is the content wrong? Contact author: