<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一、BMP图片的格式分析
1、BMP文件的大致组成
BMP文件的数据由四个部分组成:位图文件头部、位图信息头部、彩色表和图像数据阵列字节。其中彩色表不是必须的,比如24位真彩色位图就没有彩色表。
(1)位图文件头部的组成(前面14个字节)
0-1字节 | 2-5字节 | 6-9字节 | 10-13字节 | 14-17字节 | 18-21字节 | 22-25字节 | 26-27 |
BM标志 | 文件大小 | 保留 | 位图数据偏移 | 位图信息头大小 | 位图像素宽度 | 位图像素高度 | 总是1 |
424D表示BM | <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />36F00000 |
| 36000000 | 28000000 | A0000000 | 80000000 | 0100 |
| 61494字节 |
| 54字节 | 40字节 | 160字节 | 128字节 |
|
(2)位图信息头部的组成(从14字节开始,14-53共40个字节)
28-29字节 | 30-33字节 | 34-37 | 38-41 | 42-45 | 46-49 | 50-53 |
每像素字节数 | 压缩方式 | 位图数据的大小 | 水平分辨率 | 垂直分辨率 | 颜色数 | 重要颜色数 |
0x18 |
| 00F00000 |
|
|
|
|
表示24位真彩色 |
| 61440字节 |
|
|
|
|
(3)下面以一个文件的分解为例,加深对各个分量的理解。
第一个文件为 160x128,24位真彩色,用Ultraedit获得其头部如下:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
分析的信息填入上面表格的第三栏和第四栏。
对于BMP最重要的几个信息如上表用红色标注出来的。
文件头14个字节,主要是“BM”标注,文件大小等于61994个字节,最重要的是指出了图像数据的偏移等于54字节。
信息头最主要的信息时位图像素宽度等于160字节,位图像素高度等于128字节,每个像素占据24位(也就是3个字节)。图像数据总共占用的字节数等于= 160 x 128 x 3 = 61440字节,再加上头部54字节,就是整个BMP图片文件的大小 61494个字节。
(4)单色BMP格式
黑白图,每个像素只占一位,而颜色表总共有两项,占8个字节。故图像数据区的开始是 0x36 + 8 = 0x3E字节。
颜色表总是从0x36=54字节开始。
00000000代表黑色,00FFFFFF代表白色。比如F0这样一个字节,实际表示八个像素,前面四个胃白色,后面四个像素为黑色。
(5)16色BMP格式
16个颜色,每个像素占据4位,颜色表总共16项,占据64个字节,故数据区是从 0x36 + 0x40 = 0x76字节开始。
(6)256色BMP格式
256个颜色,每个颜色占据8位,颜色表总共256项,占据 256 x 4 = 1024字节。故图像数据区开始是 第0x36 + 0x400 = 0x436字节。
(7)BMP图片的重要特征
数据区里的数据是线性的,行主序,依次是 点一的B值,点一的G值,点一的R值,点二的B值,点二的G值,点二的R值,等等,需要注意的是,Windows中普遍采用了行倒向扫描的约定,即,BMP文件中原点在左下角,图像矩阵数组第一行实际是图片的最后一行。
还有一点也需要注意:Windows要求每一行的数据的长度必须是4Bytes的整数倍,如果不是,要以值为0的字节补充,如果读取的时候不处理,会得到一个倾斜的图像。如一个
2、读取BMP文件的思路
(1)图像信息结构体
建立一个BMPInfo结构体,主要包括 图像数据区偏移DataOff、彩色表偏移ColorOff、像素宽度PixWidth、像素高度PixHeight、每像素位数BitPerPix、是否压缩Compressed、图像每行字节数BytePerRow=每像素位数 * 宽度/8,补满为4的整数倍。(主要是由于每一行的数据的长度必须是4Bytes的整数倍,可能出现0填充情况)。
(2)如何读取指定行、指定列的像素
U32 GetPixel (&BMPINFO, Row,Col)
首先要定位行(相对高度而言)首的偏移,相对于数据区的偏移计算公式是(Height – Row )* BytePerRow,再计算列数相对于行首的偏移=Col * 每像素位数 / 8。故总的数据偏移 = 数据区偏移 + 行首的相对偏移 + 列偏移。
将文件指针定位到文件的偏移处,如果是24真彩色位图,则读取3个字节,转换为32位格式;如果是256色图,则还要读取彩色表:文件偏移 = 彩色表偏移 + 颜色索引x 4,再读取四个字节返回32位数据。
(3)从文件读取的RGB数据,要转换为LCD支持的格式,比如我这上面的液晶支持16位(5:6:5)格式,这样就必须经过转换,当然也可以让液晶底层操作函数接收32位颜色格式,再作内部的转换。
(4)如何确定液晶从哪一行开始显示,哪一列开始?显示多少行,显示多少列?
比如我的液晶为 160x128 最多显示128行。如果图片的高度大于128行,液晶显示是从127行开始。如果图像小于128行,比如120行,则就从119行开始显示。
如果液晶列数小于位图宽度,则显示宽度=液晶列数160。如果液晶列数大于位图宽度,则显示列数=位图宽度,截止列为=位图宽度 – 1。
同时,以后可能还要支持图片的上下、左右移动,主要是调整 液晶显示行列与位图行列的关系。
比如按下向右键,要求每次移动16个像素,什么意思呢,实际上相当于移动液晶窗口,原来左边对应位图第0列,现在对应第16列。那么向下按键,液晶窗口向下移动,本来第一行显示为图第一行,现在则显示位图的第16行。如下图所示。
文章评论(0条评论)
登录后参与讨论