Categories
Uncategorized

Audio and video entry–03-RGB turn into BMP picture

* Audio and video how-to articles directories *

BMP file format parsing

BMP file header consists of four parts, bitmap information header, the color information and graphical data.

Bitmap file header (14 bytes)

Bitmap information header (40 bytes)

Color information

Graphic data

    Header with a total of 54 bytes of header information

    RGB data section:
            Order RGB24 file storage is RGB, RGB, RGB …… RGB
            BMP file RGB data storage order is BGR, BGR, BGR … BGR

Bitmap file header

4 minutes bitmap file header portion, a total of 14 bytes

name

take up space

content

Sample Data

2 bytes

Logo, is “BM”

4 bytes

The size of the entire BMP file

2 bytes

Reserved words

2 bytes

Reserved words

4 bytes

The size of the offset number, bitmap, the bitmap file header information header + palette +

bfType BM
bfSize 0x000C0036(786486)
bfReserved1 0
bfReserved2 0
bfOffBits 0x36(54)

Bitmap information header

Bitmap information header of 40 bytes

name

take up space

content

Sample Data

4 bytes

Size of the bitmap information header, 40

4 bytes

The width of the bitmap in pixels

4 bytes

The height of the bitmap in pixels

2 bytes

Fixed value 1

2 bytes

Bits per pixel of 1 black and white, color 4-16, 8-256 color, true color 24-, 32- alpha channel

4 bytes

Compression, BI_RGB (0) is not compressed

4 bytes

The number of bytes occupied by the bitmap of all the pixels, can be set to 0 when BI_RGB

4 bytes

Horizontal resolution (pixels / m)

4 bytes

Vertical resolution (pixels / m)

4 bytes

Number of colors used, if the bitmap is 0, the number of colors is a power of two biBitCount

4 bytes

Important number of colors, 0 means that all colors are important

biSize 0x28(40)
biWidth 0x200(512)
biHeight 0x200(512)
biPlanes 1
biBitCount 0x18(24)
biCompression 0
biSizeImage 0x0C
biXPelsPerMeter 0
biYPelsPerMeter 0
biClrUsed 0
biClrImportant 0

The RGB24 pixel image data into BMP format

Conversion Code:

#include 
#include 

// 彩虹的七种颜色
u_int32_t rainbowColors[] = {
        0XFF0000, // 红
        0XFFA500, // 橙
        0XFFFF00, // 黄
        0X00FF00, // 绿
        0X007FFF, // 青
        0X0000FF, // 蓝
        0X8B00FF  // 紫
};

/*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);

    // 写入图像数据
    for (int i = 0; i < width; ++i) {

        // 当前颜色
        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];
        }
        // 当前颜色 R 分量
        u_int8_t R = (currentColor & 0xFF0000) >> 16;
        // 当前颜色 G 分量
        u_int8_t G = (currentColor & 0x00FF00) >> 8;
        // 当前颜色 B 分量
        u_int8_t B = currentColor & 0x0000FF;

        for (int j = 0; j < height; ++j) {
            // 按 BGR 顺序写入一个像素 RGB24 到文件中
            fwrite(&B, 1, 1, bitmapFile);
            fwrite(&G, 1, 1, bitmapFile);
            fwrite(&R, 1, 1, bitmapFile);
        }
    }

    // 关闭文件
    fclose(bitmapFile);
}

int main() {
    writeRGBToBmp("/Users/staff/Desktop/rainbow-700x700.bmp", 700, 700);
    return 0;
}

Examine the generated BMP picture

Congratulations! Picture to see the software recognizes our BMP images, and preview normal!
    BUT! It seems wrong with you? ! Our rainbow upside down!
    Colors of the rainbow, from top to bottom should be:
    Red -> orange -> yellow -> green -> Green -> Blue -> Purple
    This picture is:
    Purple -> Blue -> Green -> Green -> Yellow -> Orange -> Red

With pictures inverted question

BitmapInfoHeader in biHeight field,
    biHeight is positive, the bitmap scanning from bottom to top,
    biHeight is negative, the bitmap top to bottom scan.
    If this value is set and the original bitmap file scanning does not match the image may appear reversed.

The above conversion code, BitmapInfoHeader part:

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

Congratulations!

Success with pixels spell out a "real" pictures!


Code:

rgb-to-bmp

References:

Wikipedia -BMP

Bitmap (bmp) file format analysis

RGB24 converted into a BMP image

About the difference between the RGB32 and RGB24

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

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

Content is incorrect? Contact the author:


Leave a Reply