The c language parses instances of bmp images

  • 2020-05-27 06:34:06
  • OfStack

On a whim, I want to understand the format analysis of commonly used pictures. After looking through some information, I found that the most simple format was bmp, so I started with it.

BMP format

The data in this format is divided into 3 or 4 parts, in order:

The file information header (14 bytes) stores information about the file type, file size, and so on

The image information header (40 bytes) stores the size of the image, the color index, the number of bit planes, and so on

Palette (depending on the number of color indexes)

Bitmap data (determined by image size) is stored here for each pixel of information

The 1-like bmp images are all 24-bit, or true color. Every 8 bits is 1 byte, 24 bits means 3 bytes are used to store the information of every pixel. The 3 bytes correspond to the data of r, g and b3 primary colors. The storage range of each byte is 0-255.

By analogy, 32 bitmaps store r, g, b, a (Alpha channel, storage transparency) data per pixel. An 8-bit map is one that has only grayscale information, and a 2-value map that has only two colors, black or white.

File information header format

typedef struct tagBITMAPFILEHEADER {
  unsigned short bfType;   // 19778 That must be BM String, corresponding to 106 Into the system for 0x4d42,10 Into the system for 19778
  unsigned int bfSize;    //  The file size 
  unsigned short bfReserved1; // 1 As for the 0
  unsigned short bfReserved2; // 1 As for the 0
  unsigned int bfOffBits;   //  The offset from the file header to the pixel data, which is these two 

Image information header format

typedef struct tagBITMAPINFOHEADER {
  unsigned int biSize;    //  The size of this structure 
  int biWidth;        //  The image of wide 
  int biHeight;        //  Image of the high 
  unsigned short biPlanes;  // 1
  unsigned short biBitCount; // 1 The number of pixels, 1 As for the 24
  unsigned int biCompression; // 0
  unsigned int biSizeImage;  //  The size of the pixel data ,  This value should be equal to that in the header structure above bfSize-bfOffBits
  int biXPelsPerMeter;    // 0
  int biYPelsPerMeter;    // 0
  unsigned int biClrUsed;   // 0 
  unsigned int biClrImportant;// 0

Palette information

It is necessary to judge the existence of this palette information based on whether the bfOffBits of the file information header is equal to 54 (derived from the previous fixed 14+40 bytes). If so, it does not exist. Greater than exists.

The information can be extracted according to the requirements, or directly moved to the map data area to read the pixel information.

This place can be represented as a 2-dimensional array unsigned char palette[N][M], where N is the total number of color indexes and M is the number of bytes per pixel. For example, a 24-bit map is composed of 3 bytes per pixel, and M is 3. Each byte can represent a total of 256 colors from 0 to 255, so N is 256.

The array contains index information, that is, a mapping table, which identifies the corresponding relationship between the color index number and the color it represents

The bitmap data

Here all the pixel information is stored, each pixel is 1 byte, after reading out through the query palette to obtain the color information.

If the image is a bitmap of 24 - or 32-bit data, the bitmap data area is not an index but the actual pixel value. At this point, the RGB color array of each pixel in the bitmap data area is arranged:

The 24-bit RGB stores the value of each color channel of each pixel in the order of BGR. The next pixel is saved after all the color component values of a pixel are stored, without interleaved storage.

32-bit data is stored in the order of BGRA, and the rest is stored in the same way as 24-bit bitmaps.

Note: since the image height in the bitmap header is positive, the bitmap data is arranged from the lower left corner to the upper right corner of the file in line order.

That is, the first pixel to be read is the left-most pixel in the last row from the top down, followed by the pixel in the same row to the right. After reading the entire row, continue to read the second from the bottom, and then continue up until you have read all of the data.

Related articles: