BMP 储存个人理解

Posted DELH

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BMP 储存个人理解相关的知识,希望对你有一定的参考价值。

总体结构:
位图文件头BITMAPFILEHEADER
位图信息头BITMAPINFOHEADER
调色板Palette
实际的位图数据ImageDate

 

<第一部分>位图文件头BITMAPFILEHEADER,此结构长度固定占14字节

typedef struct tagBITMAPFILEHEADER {

  WORD           bfType;

  DWORD bfSize;

  WORD           bfReserved1;

  WORD           bfReserved2;

  DWORD bfOffBits;

} BITMAPFILEHEADER;

变量  大小(共14字节) 作用
bfType 2bytes

文件类型说明,可取值:

BM - windows 3.1x,95,NT,...

BA - OS/2 Bitmap Array

CI - OS/2 Color Icon

CP - OS/2 Color Pointer

IC - OS/2 Icon

PT - OS/2 Pointer

bfsize 4bytes  说明文件大小,单位:byte
bfReserved1 2bytes  保留,必须设置为0
bfReserved2 2bytes  保留,必须设置为0
bfOffBits 4bytes

 说明从文件头到实际图像数据之间的字节偏移量。

 因为位图信息头和调色板的长度不是固定的,有助于迅速定位位图数据

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<第二部分>为位图信息头BITMAPINFOHEADER,也是一个结构,其定义如下:

typedef struct tagBITMAPINFOHEADER{

  DWORD  biSize;

  LONG            biWidth;

  LONG            biHeight;

  WORD           biPlanes;

  WORD           biBitCount

  DWORD  biCompression;

  DWORD  biSizeImage;

  LONG            biXPelsPerMeter;

  LONG            biYPelsPerMeter;

  DWORD  biClrUsed;

  DWORD  biClrImportant;

} BITMAPINFOHEADER;

 变量  大小  作用
biSize 4 bytes BITMAPINFOHEADER结构需要的字节数
biWidth 4 bytes  图像宽度,像素为单位
biHeight 4 bytes

 图像高度,像素为单位

注:如果该值为正数,说明图像是倒向的;为负数,图像是正向的

大多数bmp图像是倒向的位图;

biPlanes 2 bytes  为目标设备说明颜色平面数,值为1 
biBitCount 2 bytes  说明比特数/像素,为1,4,8,16,24或32 
biCompression 4 bytes

 说明图像数据压缩类型,取值范围:

0 BI_RGB 不压缩

1 BI_RLE8 8比特游程编码(RLE),只用于8位位图

2 BI_RLE4 4比特游程编码(RLE),只用于4位位图

3 BI_BITFIELDS 比特域,用于16/32位位图

4 BI_JPEG JPEG位图含jpeg图像(仅用于打印机)

5 BI_PNG PNG位图含png图像(仅用于打印机)

biSizeImage 4 bytes  说明图像大小 biSizeImage=biWidth’ × biHeight,单位字节,当用BI_RGB时,可设置为0
biXPelsPerMeter 4 bytes  说明水平分辨率(像素/米),有符整数
biYPelsPerMeter 4 bytes   说明垂直分辨率(像素/米),有符整数
biClrUsed 4 bytes  说明位图实际使用的色彩表中的颜色索引,为0看后续说明
biClrImportant 4 bytes  说明对图像显示有重要影响的颜色索引数目,为0表示都重要

 

 

<第三部分>为调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,前面已经讲过,是不需要调色板的,BITMAPINFOHEADER后直接是位图数据。可以理解为biClrUsed参数不为0时,有调色板。

调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2biBitCount个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:

typedef struct tagRGBQUAD {

BYTE    rgbBlue; //该颜色的蓝色分量

BYTE    rgbGreen; //该颜色的绿色分量

BYTE    rgbRed; //该颜色的红色分量

BYTE    rgbReserved; //保留值

} RGBQUAD;

比如索引值biClrUsed为64,即有64个调色盘,则总偏移量计算14bytes+40bytes+64*4bytes=310bytes

<第四部分>实际的图象数据。

(1)对于用到调色板的位图,图象数据就是该象素颜在调色板中的索引值。即某一点只储存一个索引值,按照这个索引值在调色板中查找对应像素作为它的像素

(2)对于真彩色图,图象数据就是实际的R、G、B值。下面针对2色、16色、256色位图和真彩色位图分别介绍。  每个像素点都是按调色板的格式储存的,也可以理解为全是调色板

对于2色位图,用1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。

对于16色位图,用4位可以表示一个象素的颜色,所以一个字节可以表示2个象素。

对于256色位图,一个字节刚好可以表示1个象素。

要注意两点:

(1)    每一行的字节数必须是4的整倍数,如果不是,则需要补齐。这在前面介绍biSizeImage时已经提到了。

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

<对齐>

Windows默认的扫描的最小单位是4字节,如果数据对齐满足这个值能够大幅提升图像读取速度。因此,BMP图像顺应了这个要求,要求每行的数据的长度必须是4的倍数,如果不够需要进行比特填充(以0填充)。填充后的每行的字节数为:rowsize=4*ceil(BPP*Width/32)

<其他情况>

上述主要是PC机上的位图文件的构成,对于嵌入式平台,可能在调色板数据段与PC机的不同。如在嵌入式平台上常见的16位r5g6b5位图实际上采用的掩模的方式而不是索引的方式来表示图像。此时,在调色板数据段共有四个部分,每个部分为四个字节,实际表示的是彩色版规范。即:

  第一个部分是红色分量的掩模

  第二个部分是绿色分量的掩模

 第三个部分是蓝色分量的掩模

 第四个部分是Alpha分量的掩模(缺省为0)

  1111100000000000(二进制),是蓝红分量的掩码。 
  0000011111100000(二进制),是绿色分量的掩码。 
  0000000000011111(二进制),是蓝色分量的掩码。

在每个像素值的两个字节16位中,按从高到低取5、6、5位分别就是r、g、b分量值;把分量值r、g、b值分别左移操作3、2、3位就可以补齐每个分量为一个字节,再把这三个字节按BGR组合,就可以转换为24位标准BMP格式

以上是关于BMP 储存个人理解的主要内容,如果未能解决你的问题,请参考以下文章

BMP图片分析

浅谈数位dp

js原型和原型链个人理解(我的理解)

对结对编程的个人理解:

对于框架的一些个人理解

Volatile个人理解