Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622790
  • 博文数量: 178
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 2162
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-12 20:06
文章分类

全部博文(178)

文章存档

2011年(1)

2010年(94)

2009年(86)

我的朋友

分类:

2010-03-03 09:14:52

1、BMP文件格式简单介绍
   BMP文件是一种像素文件,它保存了一幅图象中所有的像 素。这种文件格式可以保存单色位图、16色或256色索引模式像素图、24位真彩色图象,每种模式种单一像素的大小分别为1/8字节,1/2字节,1字节 和3字节。目前最常见的是256色BMP和24位色BMP。这种文件格式还定义了像素保存的几种方法,包括不压缩、RLE压缩等。常见的BMP文件大多是 不压缩的。
   这里为了简单起见,我们仅讨论24位色、不使用压缩的BMP。(如果你使用Windows自带的画图程序,很容易绘制出一个符合以上要 求的BMP)
Windows所使用的BMP文件,在开始处有一个文件头,大小为54字节。保存了包括文件格式标识、颜色数、图象大小、压缩方式等 信息,因为我们仅讨论24位色不压缩的BMP,所以文件头中的信息基本不需要注意,只有“大小”这一项对我们比较有用。图象的宽度和高度都是一个32位整 数,在文件中的地址分别为0x00120x0016,于是我们可以使用以下代码来读取图象的大小信息:

GLint width, height; // 使 用OpenGL的GLint类型,它是32位的。
                     // 而C语言本身的int则不一定是32位的。
FILE* pFile;
// 在 这里进行“打开文件”的操作
fseek(pFile, 0x0012, SEEK_SET);         // 移动到0x0012位置
fread(&width, sizeof(width), 1, pFile); // 读 取宽度
fseek(pFile, 0x0016, SEEK_SET);         // 移动到0x0016位置
                                        // 由 于上一句执行后本就应该在0x0016位置
                                        // 所以这一句 可省略
fread(&height, sizeof(height), 1, pFile); // 读取高度

54个字 节以后,如果是16色或256色BMP,则还有一个颜色表,但24位色BMP没有这个,我们这里不考虑。接下来就是实际的像素数据了。24位色的BMP文 件中,每三个字节表示一个像素的颜色。
注意,OpenGL通常使用RGB来表示颜色,但BMP文件则采用BGR,就是说,顺序被反过来了。
另 外需要注意的地方是:像素的数据量并不一定完全等于图象的高度乘以宽度乘以每一像素的字节数,而是可能略大于这个值。原因是BMP文件采用了一种“对齐” 的机制,每一行像素数据的长度若不是4的倍数,则填充一些数据使它是4的倍数。这样一来,一个17*15的24位BMP大小就应该是834字节(每行17 个像素,有51字节,补充为52字节,乘以15得到像素数据总长度780,再加上文件开始的54字节,得到834字节)。分配内存时,一定要小心,不能直 接使用“图象的高度乘以宽度乘以每一像素的字节数”来计算分配空间的长度,否则有可能导致分配的内存空间长度不足,造成越界访问,带来各种严重后果。
一 个很简单的计算数据长度的方法如下:

int LineLength, TotalLength;
LineLength = ImageWidth * BytesPerPixel; // 每 行数据长度大致为图象宽度乘以
                                         // 每像素的字节数
while( LineLength % 4 != 0 )             // 修 正LineLength使其为4的倍数
    ++LineLenth;
TotalLength = LineLength * ImageHeight;  // 数 据总长 = 每行长度 * 图象高度

这并不是效率最高的方法,但由于这个修正本身运算量并不大,使用频率也不高,我们就不需要再考虑更快 的方法了。
阅读(3061) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~