Bmp图片格式介绍

Bmp图片格式介绍

介绍

BMP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,能够被多种Windows应用程序所支持。随着Windows操作系统的流行与丰富的Windows应用程序的开发,BMP位图格式理所当然地被广泛应用。这种格式的特点是包含的图像信息较丰富,几乎不进行压缩,但由此导致了它与生俱来的缺点–占用磁盘空间过大

文件数据结构

bmp 格式图片的文件头长度绝大多数都是 54 字节,其中包括 14 字节的 位图文件头(head)以及 40 字节的 DIB (Device Independent Bitmap) 位图信息数据头(BItmap Information Header)。

位图文件头(14 bytes)

地址(hex) 字节长度(byte) 描述
00 2 固定头文件字段,内容为0x424D
02 4 bmp文件大小(little endian)
06 2 预留字段
08 2 预留字段
0A 4 图片信息的开始位置

位图信息数据头(40bytes)

地址(hex) 字节长度(byte) 描述
0E 4 位图信息数据头的大小 40bytes
12 4 图像宽度(little endian)
16 4 图像高度(little endian)
1A 2 色彩平面的数量,默认为1
1C 2 每像素用多少bit表示
1E 4 图片采用的压缩方式,通常不压缩即BL_RGB,对应值0
22 4 图片大小(原始位图数据大小)对于不压缩的图片,默认为0
26 4 横向分辨率(像素/米)
2A 4 纵向分辨率(像素/米)
2E 4 调试板中颜色数量,默认为0
32 4 重要颜色的数量,默认为0

原始位图数据 Raw Bitmap Data

拿最常见的 24BPP RGB (24 比特每像素,红绿蓝三通道) 位图来说,每种颜色需要 8 比特,或者说 1 字节,来存储。在二进制文件中,通常情况下,RGB 按照蓝、绿、红的顺序依次表示图片中的像素点,而 RGBA 则按照蓝、绿、红、透明的顺序(从左下开始,横向逐行向上扫描)。特殊时候,也会出现顺序与上述情况不同的特例,这时色彩顺序会写在 DIB Header 的 Bit Fields 中,以不同色彩通道的 Mask 的形式进行规定。由于 BI_BITFIELDS 也是一种压缩方式,而通常 BMP 不采用任何压缩方式,所以绝大多数时候,我们都是按照前面说的顺序进行排序。

地址(hex) 字节长度(byte) 描述(big endian)
36 4 00 00 FF 00 Red Channel bit mask
3A 4 00 FF 00 00 Green Channel bit mask
3E 4 FF 00 00 00 Blue Channel bit mask
42 4 00 00 00 FF Alpha Channel bit mask

主流的 CPU 每次从内存中读取并处理数据块(chunk),且通常为 32 比特(4 字节)。因此,为了提升读取效率,位图每行的数据(字节)都需要是 4 的倍数,字节对齐

Row_Size = (BitPerPixel * Image_Width + 31) / 32 * 4

每行的字节数等于:每像素比特数乘以图片宽度31 的和除以 32,并向下取整,最后乘以 4

Pix_Array_Size = Row_Size * Image_Height

原始位图数据大小等于:每行的字节数乘以图像高度(也就是总行数)

文件大小 = 原始位图数据大小 + 文件头大小

Bmp图片格式介绍_第1张图片

代码表示bitmap数据

BitMap Head

#pragma pack(1)
typedef struct {
    unsigned short bfType;      // "BM"
    unsigned int bfSize;        // 文件大小
    unsigned short bfReserved1; // 保留,必须设置为0
    unsigned short bfReserved2; // 保留,必须设置为0
    unsigned int bfOffBits;     // 从文件头到像素数据的偏移
} BitMapFileHeader;

BitMap Info Header

typedef struct{
    unsigned int biSize;        // 此结构体的大小
    int biWidth;                // 图像的宽
    int biHeight;               // 图像的高
    unsigned short biPlanes;    // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1
    unsigned short biBitCount;  // 一像素所占的位数,一般为24
    unsigned int biCompression; // 说明图象数据压缩的类型,0为不压缩。
    unsigned int biSizeImage;   // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBits
    int biXPelsPerMeter;        // 说明水平分辨率,用象素/米表示。一般为0
    int biYPelsPerMeter;        // 说明垂直分辨率,用象素/米表示。一般为0
    unsigned int biClrUsed;     // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
    unsigned int biClrImportant;// 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BitMapInfoHeader;

rgb

// 24bit
typedef struct {
    unsigned char rgblue;
    unsigned char rgbgreen;		
    unsigned char rgbred;
    unsigned char rgbreserved;
} PixelInfo;

代码demo

读取bmp文件数据头
#ifndef _BMP_H_
#define _BMP_H_

#pragma pack(1)

typedef struct {
    unsigned short bfType;      // "BM"
    unsigned int bfSize;        // 文件大小
    unsigned short bfReserved1; // 保留,必须设置为0
    unsigned short bfReserved2; // 保留,必须设置为0
    unsigned int bfOffBits;     // 从文件头到像素数据的偏移
} BitMapFileHeader;

typedef struct{
    unsigned int biSize;        // 此结构体的大小
    int biWidth;                // 图像的宽
    int biHeight;               // 图像的高
    unsigned short biPlanes;    // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1
    unsigned short biBitCount;  // 一像素所占的位数,一般为24
    unsigned int biCompression; // 说明图象数据压缩的类型,0为不压缩。
    unsigned int biSizeImage;   // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBits
    int biXPelsPerMeter;        // 说明水平分辨率,用象素/米表示。一般为0
    int biYPelsPerMeter;        // 说明垂直分辨率,用象素/米表示。一般为0
    unsigned int biClrUsed;     // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。
    unsigned int biClrImportant;// 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BitMapInfoHeader;

// 24bit
typedef struct {
    unsigned char rgblue;
    unsigned char rgbgreen;		
    unsigned char rgbred;
    unsigned char rgbreserved;
} PixelInfo;

#endif

#include 
#include "bmp.h"

void show_bmp_file_head(BitMapFileHeader *data)
{
    printf("#########################################\n");
    printf("bfType %x\n", data->bfType);
    printf("bfSize %d\n", data->bfSize/1024);
    printf("bfOffBits %d\n", data->bfOffBits);
}

void show_bmp_info_head(BitMapInfoHeader *data)
{
    printf("#########################################\n");
    printf("biSize %d\n", data->biSize);
    printf("biWidth %d\n", data->biWidth);
    printf("biHeight %d\n", data->biHeight);
    printf("biPlanes %d\n", data->biPlanes);
    printf("biBitCount %d\n", data->biBitCount);
    printf("biCompression %d\n", data->biCompression);
    printf("biXPelsPerMeter %d\n", data->biXPelsPerMeter);
    printf("biYPelsPerMeter %d\n", data->biYPelsPerMeter);
    printf("biClrUsed %d\n", data->biClrUsed);
    printf("biClrImportant %d\n", data->biClrImportant);
}

void show_bmp_rgb(PixelInfo *data)
{
    printf("#########################################\n");
    printf("rgblue %2x\n", data->rgblue);
    printf("rgbgreen %2x\n", data->rgbgreen);
    printf("rgbred %2x\n", data->rgbred);
}

int main(int argc, char *argv[])
{
    FILE *fp = NULL;
    BitMapFileHeader    FileHead;
    BitMapInfoHeader    InfoHead;
    PixelInfo           rgbinfo;
    char *ptr = NULL;
    int i, j;
    
    fp = fopen(argv[1], "rb");
    if(fp == NULL)
    {
        perror("open bmp file error");
        return -1;
    }

    fread(&FileHead, sizeof(BitMapFileHeader), 1, fp);
    fread(&InfoHead, sizeof(BitMapInfoHeader), 1, fp);
    show_bmp_file_head(&FileHead);
    show_bmp_info_head(&InfoHead);
    show_bmp_rgb(&rgbinfo);
    
    ptr = (unsigned char *)malloc(FileHead.bfSize);
    if(ptr == NULL)
    {
        perror("malloc ptr fail\n");
        return 0;
    }
    for(i = 0; i <= InfoHead.biHeight; i++)
    {
        for(j = 0; j <= InfoHead.biWidth; j++)
        {
            fread(&rgbinfo, sizeof(PixelInfo), 1, fp);
            *ptr = 0xff << 24 | rgbinfo.rgbred << 16 |  rgbinfo.rgbgreen << 8 | rgbinfo.rgblue;
            memset(&rgbinfo, 0, sizeof(PixelInfo));
            ptr++;
            if((rgbinfo.rgbred == 255) && (rgbinfo.rgbgreen == 255) && (rgbinfo.rgblue == 255))
                printf(" ");
            else
                printf("#");
        }
        printf("\n");
    } 
    
    fclose(fp);
    return 0;
}
lin@u-android:~/lin/workspace/demo_project/bmp$ gcc -o bmp_test show_bmp_head.c 
lin@u-android:~/lin/workspace/demo_project/bmp$ ./bmp_test ./test.bmp 
#########################################
bfType 4d42
bfSize 459
bfOffBits 54
#########################################
biSize 40
biWidth 507
biHeight 309
biPlanes 1
biBitCount 24
biCompression 0
biXPelsPerMeter 0
biYPelsPerMeter 0
biClrUsed 0
biClrImportant 0

你可能感兴趣的:(libdrm,linux,linux,drm)