Introduction to audio and video-03-rgb into bmp picture

Time:2020-6-6

Audio and video introduction article directory

Analysis of BMP file format

BMP file consists of file header, bitmap information header, color information and graphics data.

Bitmap file header (14 bytes) Bitmap header (40 bytes) Color information graphic data
  • The file header and information header are 54 bytes in total
  • RGB data section:

RGB24 file storage order is RGB, RGB, RGB… RGB
The order of RGB data storage of BMP file is BGR, BGR, BGR… BGR

bitmap-file header

Bitmap file header is divided into 4 parts, 14 bytes in total

name Occupied space content Sample data
bfType 2 bytes Logo is “BM” BM
bfSize 4 bytes Size of the entire BMP file 0x000C0036(786486)
bfReserved1 2 bytes Reserved word 0
bfReserved2 2 bytes Reserved word 0
bfOffBits 4 bytes Offset, that is, the size of bitmap file header + bitmap information header + palette 0x36(54)

Bitmap header

Bitmap header 40 bytes in total

name Occupied space content Sample data
biSize 4 bytes The size of the bitmap header, which is 40 0x28(40)
biWidth 4 bytes The width of the bitmap, in pixels 0x200(512)
biHeight 4 bytes The height of the bitmap, in pixels 0x200(512)
biPlanes 2 bytes Fixed value 1 1
biBitCount 2 bytes Bits per pixel 1-black and white, 4-16 colors, 8-256 colors, 24 true colors, 32 with alpha channel 0x18(24)
biCompression 4 bytes Compression mode, Bi_ RGB (0) is uncompressed 0
biSizeImage 4 bytes Bytes occupied by all pixels of bitmap, Bi_ Can be set to 0 when RGB 0x0C
biXPelsPerMeter 4 bytes Horizontal resolution (pixel / meter) 0
biYPelsPerMeter 4 bytes Vertical resolution (pixel / meter) 0
biClrUsed 4 bytes If the number of colors used by bitmaps is 0, the number of colors is 2 to the power of biBitCount 0
biClrImportant 4 bytes Important number of colors, 0 means all colors are important 0

Convert RGB24 pixel data to BMP format picture

Conversion code:

#include <stdio.h>
#include <stdlib.h>

//Seven colors of rainbow
u_int32_t rainbowColors[] = {
        0xxff0000, // red
        0xffa500, // orange
        0xfff00, // yellow
        0x00ff00, // Green
        0x007fff, // Green
        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 分量
        u_int8_t R = (currentColor & 0xFF0000) >> 16;
        //Current color G 分量
        u_int8_t G = (currentColor & 0x00FF00) >> 8;
        //Current color B 分量
        u_int8_t B = currentColor & 0x0000FF;

        for (int j = 0; j < height; ++j) {
            //Write a pixel RGB24 to the 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

The picture viewing software has recognized our BMP picture. The preview is normal!
BUT! What seems to be wrong?! Our rainbow is upside down!
The color of the rainbow, from top to bottom, should be:
Red – > Orange – > yellow – > Green – > Blue – > purple
This picture is:
Purple blue green yellow orange red

Introduction to audio and video-03-rgb into bmp picture

Dealing with picture handstand

The biheight field in BITMAPINFOHEADER,
Biheight is positive, bitmap scans from bottom to top,
Biheight is negative and bitmap scans 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 above transformation code, BITMAPINFOHEADER part:

// infoHeader.biHeight = height;
infoHeader.biHeight = -height;

Introduction to audio and video-03-rgb into bmp picture

Congratulations!

Successfully spell out a “real” picture with pixel points!


code:

rgb-to-bmp

reference material:

Wikipedia BMP

Analysis of bitmap (BMP) file format

RGB24 to BMP image

On the difference between rgb32 and RGB24

non-dword-aligned-pixel-to-dword-aligned-bitmap

generate-bmp-file-from-array-of-rgb-values

Wrong content? Contact author:

Introduction to audio and video-03-rgb into bmp picture