1 - BMP 图片编码

前言:在这篇笔记中,引用了别人博客之中的相关内容,在此附上相关链接,以作为参考资料。
1、BMP 文件格式详解
2、BMP 文件结构

1、数据结构

位图文件整体通常由文件头、信息表、颜色表、图像数据四个部分的字节连续组成。其中颜色表在部分的图片文件之中,可省略。

组成类型简介
位图文件头(bitmapFileHeader)固定大小为 14 个字节,其中包含 Bmp 图片类型,以及文件大小和位图起始位置等信息
位图信息头(bitmapInformationHeader)固定大小为40个字节,用于说明位图的尺寸等信息
彩色表/调色板(colorTable)固定大小为4个字节,用于图片色彩值的映射情况(部分省略)
位图数据(bitmapData)真实存储的图像数据

2、位图文件头

字段名大小(单位:字节)描述
bfType2用于说明文件类型,Bmp 文件类型前的头两个字节指明必须是0x424D,即字符串“BM”;否则认为不是标准的 Bmp。 但在文件读取的时候,低位在前,因此其读取出来的真实数据即为:&H4D42
bfSize4用于说明文件的整体大小,包括这14个字节,以字节为单位
bfReserved12保留属性,设置为0
bfReserved22保留属性,设置为0
bfOffsetBytes4位图数据区在 Bmp 文件中的位置偏移量,此时的偏移量不得小于 54 字节(即只包含位图文件头、位图信息头),其不为固定数据常量

3、位图信息头

字段名大小(单位:字节)描述
biSize4信息头大小,其为固定字节常量,40
biWidth4指明图像宽度信息
biHeight4指明图像高度信息
biPlanes2位平面数,必须为1
biBitCount2说明每像素的位数。常用的值为1(黑白二色图)、4(16色图)、8(256色)、24(真彩色图)或32(新的.bmp格式支持32位色)
biCompression4压缩类型,当值为 0 表示不压缩,1 表示RLE8压缩,2 表示RLE4压缩,3 表示每个像素值由指定的掩码决定
biSizeImage4压缩图像大小字节数 biSizeImage = lineBytes(真实行字节数) × biHeight,其中 lineBytes 必须是 4 的整倍数,(不是biWidth(图像的宽度),而是lineBytes,表示大于或等于 biWidth 的,最接近 4 的整倍数)
biXPelsPerMeter4水平分辨率,单位是每米的象素个数
biYPelsPerMeter4垂直分辨率,单位是每米的象素个数
biClrUsed4位图实际用到的色彩数,如果该值为零,则用到的颜色数为2^biBitCount
biClrImportant4本位图中重要的色彩数,如果该值为零,则认为所有的颜色都是重要的

注解1:为何是 lineBytes,而不是 biWidth ?

        答:操作系统默认的扫描的最小单位是 4 字节,如果数据对齐满足这个值的话,可以加快数据的获取速度。因此,BMP 图像顺应了这个要求,要求每行的数据的长度必须是 4 的倍数,如果不够需要进行比特填充(以 0 填充),这样可以达到按行的快速存取。此时,位图数据区的像素个数就未必是 图片宽 × 图片高,因为每行可能还需要进行比特填充。

注解2:lineBytes 的相关计算公式:

        1、lineBytes = (biWidth * biBitCount + 31) / 32 * 4
        2、解释:
                 ①、计算未进行填充时一行数据所占的位数:biWidth * biBitCount
                 ②、将位数转换为未对齐时一行数据所占的字节数:(biWidth * biBitCount + 7) / 8(进位取整)
                 ③、进行计算对齐时一行数据所占的字节单元数(单位:4Byte):[(biWidth * biBitCount + 7) / 8 + 3]) / 4(同样需要进一步的进位取整,可将上述步骤②的结果值作为一个整体变量来进行运算)
                 ④、公式整理、化简:lineBytes = (biWidth * biBitCount + 31) / 32 * 4

4、颜色表

字段名大小(单位:字节)描述
rgbBlue1该颜色的蓝色分量
rgbGreen1该颜色的绿色分量
rgbRed1该颜色的红色分量
rgbAlpha1该颜色的通明分量,当不为 32 位真彩图的时候,该值为 0
  • 调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。
  • 它在文件中的布局就像一个二维数组 palette[N][4],其中N表示总的颜色索引数,每行的四个元素分别表示该索引对应的 B、G、R和 Alpha 的值,每个分量占一个字节。
  • 如不设透明通道时,Alpha为0。
  • 24位真彩色是无调色板部分的,位图信息头(bitBmpInfoHeader)后直接是位图数据。

5、图像数据

  • 字节要求:每一行的字节数必须是4的整倍数,如果不是,则需要补齐。如 241 补齐为 244.

  • 读取顺序:一般来说,BMP文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推 ,最后得到的是最上面一行的最右一个象素。

  • 存储方式:24位真彩色图,按照 B、G、R 的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个像素,不进行交织存储。32位数据,按照 B、G、R、A 的顺序存储,其余与24位位图的方式一样。

6、结构体示例

#ifndef __BmpFormat_H
#define __BmpFormat_H

typedef unsigned char   uint_8;     // 一个字节
typedef unsigned short  uint_16;    // 两个字节
typedef unsigned int    uint_32;    // 四个字节


// 位图文件头,固定大小为 14 个字节,用于判断 Bmp 图片类型,以及文件大小和位图起始位置等
typedef struct BITMAPFILEHEADER {
    uint_16     bfType;             // 文件类型,Bmp 文件类型前的头两个字节指明必须是0x424D,即字符串“BM”;否则认为不是标准的 Bmp 文件类型
    uint_32     bfSize;             // 说明文件的大小,包括这14个字节,以字节为单位 
    uint_16     bfReserved1;        // 保留,设置为0 
    uint_16     bfReserved2;        // 保留,设置为0
    uint_32     bfOffsetBytes;      // 说明从 位图文件头(BITMAPFILEHEADER)结构开始到实际的图像数据之间的字节偏移量,以字节为单位 
} bitBmpFileHeader;


//位图信息头,固定大小为40个字节,用于说明位图的尺寸等信息
typedef struct BITMAPINFOHEADER {
    uint_32     biSize;             // 信息头大小
    uint_32     biWidth;            // 图像宽度
    uint_32     biHeight;           // 图像高度
    uint_16     biPlanes;           // 位平面数,必须为1
    uint_16     biBitCount;         // 每像素位数。常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)或32(新的.bmp格式支持32位色)
    uint_32     biCompression;      // 压缩类型:有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些Windows定义好的常量)
    uint_32     biSizeImage;        // 压缩图像大小字节数 biSizeImage=biWidth’ × biHeight,biWidth’必须是4的整倍数,(所以不是biWidth,而是biWidth’,表示大于或等于biWidth的,最接近4的整倍数)
    uint_32     biXPelsPerMeter;    // 水平分辨率,单位是每米的象素个数
    uint_32     biYPelsPerMeter;    // 垂直分辨率,单位是每米的象素个数
    uint_32     biClrUsed;          // 位图实际用到的色彩数,如果该值为零,则用到的颜色数为2^biBitCount
    uint_32     biClrImportant;     // 本位图中重要的色彩数,如果该值为零,则认为所有的颜色都是重要的。
} bitBmpInfoHeader;  


/****************************************************************************************************************************************
 * 调色板信息,4个字节
 * 说明:调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。
 * 它在文件中的布局就像一个二维数组palette[N][4],其中N表示总的颜色索引数,每行的四个元素分别表示该索引对应的 B、G、R和 Alpha 的值,每个分量占一个字节。
 * 如不设透明通道时,Alpha为0。
 * 真彩色是无调色板部分的,位图信息头(bitBmpInfoHeader)后直接是位图数据。
****************************************************************************************************************************************/
typedef struct BITMAPRGBAlpha {
    uint_8      rgbBlue;            // 该颜色的蓝色分量
    uint_8      rgbGreen;           // 该颜色的绿色分量
    uint_8      rgbRed;             // 该颜色的红色分量
    uint_8      rgbAlpha;           // 该颜色的透明分量
} bmpColorPalette;


/****************************************************************************************************************************************
 * 位图数据信息 - bitmapData
 * 字节要求:每一行的字节数必须是4的整倍数,如果不是,则需要补齐。如 241 补齐为 244.
 * 读取顺序:一般来说,BMP文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,
             然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推 ,最后得到的是最上面一行的最右一个象素。
 * 存储方式:24位真彩色图,按照 B、G、R 的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个像素,不进行交织存储。
             32位数据,按照 B、G、R、A 的顺序存储,其余与24位位图的方式一样。
****************************************************************************************************************************************/


#endif // !__BmpFormat_H
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值