矢量图格式?位图和矢量图的区别?BMP位图格式详解二(2)
0E-11:00000028h = 40,这就是说我这个位图信息头的大小为40个字节,明信片格式,。前面我们已经说过位图信息头一般有40个字节,既然是这样,为什么这里还要给一个字段来说明呢?这里涉及到一些历史,其实位图信息头原本有很多大小的版本的。我们看一下下表:
出于兼容性的考虑,大多数应用使用了旧版的位图信息头来保存文件。而 OS/2 已经过时了,因此现在最常用的格式就仅有V3 header了。因此,我们在前面说位图信息头的大小为40字节。
12-15:00000100h = 256,图像宽为255像素,与文件属性一致。
16-19:00000100h = 256,图像高为255像素,与文件属性一致。这是一个正数,说明图像数据是从图像左下角到右上角排列的。
1A-1B:0001h, 该值总为1。
1C-1D:0008h = 8, 表示每个像素占8个比特,即该图像共有256种颜色。
1E-21:00000000h,BI_RGB, 说明本图像不压缩。
22-25:00000000h,图像的大小,因为使用BI_RGB,所以设置为0。
26-29:00000000h,水平分辨率,缺省。
2A-2D:00000000h,垂直分辨率,缺省。
2E-31:00000100h = 256,说明本位图实际使用的颜色索引数为256,与1C-ID得到的结论一致。
32-35:00000100h = 256,说明本位图重要的颜色索引数为256,与前面得到的结论一致。
三、调色板
下面的数据就是调色板了。前面也已经提过,调色板其实是一张映射表,标识颜色索引号与其代表的颜色的对应关系。它在文件中的布局就像一个二维数组palette[N][4],其中N表示总的颜色索引数,每行的四个元素分别表示该索引对应的B、G、R和Alpha的值,每个分量占一个字节。如不设透明通道时,Alpha为0。因为前面知道,本图有256个颜色索引,因此N = 256。索引号就是所在行的行号,对应的颜色就是所在行的四个元素,位图的格式。这里截取一些数据来说明:
索引:(蓝,绿,红,Alpha)
0号:(fe,fa,fd,00)
1号:(fd,f3,fc,00)
2号:(f4,f3,fc,00)
3号:(fc,f2,f4,00)
4号:(f6,f2,f2,00)
5号:(fb,f9,f6,00) 等等。
一共有256种颜色,每个颜色占用4个字节,就是一共1024个字节,再加上前面的文件信息头和位图信息头的54个字节加起来一共是1078个字节。也就是说在位图数据出现之前一共有1078个字节,与我们在文件信息头得到的信息:文件头到文图数据区的偏移为1078个字节一致!
四、位图数据
下面就是位图数据了,每个像素占一个字节,取得这个字节后,以该字节为索引查询相应的颜色,并显示到相应的显示设备上就可以了。
注意:由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到右上角,以行为主序排列的。
也即我们见到的第一个像素60是图像最左下角的数据,第二个人像素60为图像最后一行第二列的数据,…一直到最后一行的最后一列数据,后面紧接的是倒数第二行的第一列的数据,依此类推,位图格式详解。
如果图像是24位或是32位数据的位图的话,位图数据区就不是索引而是实际的像素值了。下面说明一下,此时位图数据区的每个像素的RGB颜色阵列排布:
24位RGB按照BGR的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。
32位数据按照BGRA的顺序存储,其余与24位位图的方式一样。
像素的排布规则与前述一致。
对齐规则
填充后的每行的字节数为:
,其中BPP(Bits Per Pixel)为每像素的比特数。在程序中,我们可以表示为:
int iLineByteCnt = (((m_iImageWidth * m_iBitsPerPixel) + 31) >> 5) << 2;
这样,位图数据区的大小为:
m_iImageDataSize = iLineByteCnt * m_iImageHeight;
我们在扫描完一行数据后,也可能接下来的数据并不是下一行的数据,可能需要跳过一段填充数据:
skip = 4 - ((m_iImageWidth * m_iBitsPerPixel)>>3) & 3;
五、拾遗
我不动