VC++数字图像处理(3)

2019-03-11 13:37

— biHeight:位图的高度,以像素为单位。 — biPlanes:目标设备的级别,必须是1。

— biBitCount:每个像素所占的位数(bit),其值必须为1(黑白图像)、4(16色图)、8(256色)、24(真彩色图),新的BMP格式支持32位色。

— biCompresssion:位图压缩类型,有效的值为BI_RGB(未经压缩)、BI_RLE8、BI_RLE4、BI_BITFILEDS(均为Windows定义常量)。这里只讨论未经压缩的情况,即biCompression=BI_RGB。 — biSizeImage:实际的位图数据占用的字节数,该值的大小在第4部分位图数据中有具体解释。 — biXPelsPerMeter:指定目标设备的水平分辨率,单位是像素/米。 — biYPelsPerMeter:指定目标设备的垂直分辨率,单位是像素/米。

— biClrUsed:位图实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次幂。 — biClrImportant:位图显示过程中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。

第3部分为颜色表。颜色表实际上是一个RGBQUAD结构的数组,数组的长度由biClrUsed指定(如果该值为零,则由biBitCount指定,即2的biBitCount次幂个元素)。RGBQUAD结构是一个结构体类型,占4个字节,其定义如下:

typedef struct tagRGBQUAD {

BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; }RGBQUAD;

RGBQUAD结构的各个域的详细说明如下:

— rgbBlue:该颜色的蓝色分量; — rgbGreen:该颜色的绿色分量; — rgbRed:该颜色的红色分量; — rgbReserved:保留字节,暂不用。

有些位图需要颜色表;有些位图(如真彩色图)则不需要颜色表,颜色表的长度由BITMAP

INFOHEADER结构中biBitCount分量决定。对于biBitCount值为1的二值图像,每像素占1bi

t,图像中只有两种(如黑白)颜色,颜色表也就有21=2个表项,整个颜色表的大小为

个字节;对于biBitCount值为8的灰度图像,每像素占8bit,图

像中有28=256种颜色,颜色表也就有256个表项,且每个表项的R、G、B分量相等,整个颜色表的大小为

个字节;而对于biBitCount=24的真彩色图像,由于每

像素3个字节中分别代表了R、G、B三分量的值,此时不需要颜色表,因此真彩色图的BITMAPINFOHEADER结构后面直接就是位图数据。

第4部分是位图数据,即图像数据,其紧跟在位图文件头、位图信息头和颜色表(如果有颜色表的话)之后,记录了图像的每一个像素值。对于有颜色表的位图,位图数据就是该像素颜色在调色板中的索引值;对于真彩色图,位图数据就是实际的R、G、B值(三个分量的存储顺序是B、G、R)。下面分别就2色、16色、256色和真彩色位图的位图数据进行说明:

— 对于2色位图,用1位就可以表示该像素的颜色,所以1个字节能存储8个像素的颜色值。 — 对于16色位图,用4位可以表示一个像素的颜色。所以一个字节可以存储2个像素的颜色值。 — 对于256色位图,1个字节刚好存储1个像素的颜色值。 — 对于真彩色位图,3个字节才能表示1个像素的颜色值。

需要注意两点:

第一,Windows规定一个扫描行所占的字节数必须是4的倍数,不足4的倍数则要对其进行扩充。假设图像的宽为biWidth个像素、每像素biBitCount个比特,其一个扫描行所占的真实字节数的计算公式如下:

DataSizePerLine = (biWidth * biBitCount /8+ 3) / 4*4

那么,不压缩情况下位图数据的大小(BITMAPINFOHEADER结构中的biSizeImage成员)计算如下:

biSizeImage = DataSizePerLine * biHeight

第二,一般来说,BMP文件的数据是从图像的左下角开始逐行扫描图像的,即从下到上、从左到右,将图像的像素值一一记录下来,因此图像坐标零点在图像左下角。

1.2.2 BMP图像文件的读写

分析了BMP文件结构后,让我们用简单的C程序实现一个给定BMP位图文件的读写操作,来进一步巩固对图像数据的理解,这也是我们后续图像可视化编程的基础。此部分的代码以及后面两节所讲述的代码在工程chap1-1中的bmpReadWrite.cpp文件中,读者可以查阅。

1.BMP文件的读入

BMP文件分为4个组成部分,那么BMP文件的读入也要按照4个组成部分依次进行处理,即先处理BITMAPFILEHEADER结构,然后是BITMAPINFOHEADER结构、颜色表,最后是位图数据。

首先,有关BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD等结构的定义包含在头文件“Windows.h”中,应把其包含进来。

#include \

其次,为了后面对图像进行修改及存盘方便,我们定义了几个全局变量,用来存放读入图像的位图数据、宽、高、颜色表及每像素位数等信息。所定义的全局变量如下: unsigned char *pBmpBuf;//读入图像数据的指针 int bmpWidth;//图像的宽 int bmpHeight;//图像的高

RGBQUAD *pColorTable;//颜色表指针 int biBitCount;//图像类型,每像素位数

根据BMP文件结构,BMP文件读入操作的基本流程如图1-8所示。

图1-8 BMP文件读入操作流程图

readBmp()函数实现了BMP文件的读取操作,下面的代码是对readBmp()函数的说明和实现。

/*********************************************************************** * 函数名称: * readBmp() *

*函数参数:

* char *bmpName -文件名字及路径 * *返回值:

* 0为失败,1为成功 *

*说明:给定一个图像文件名及其路径,读图像的位图数据、宽、高、颜色表及每像素 * 位数等数据进内存,存放在相应的全局变量中

***********************************************************************/ bool readBmp(char *bmpName) {

//二进制读方式打开指定的图像文件 FILE *fp=fopen(bmpName,\ if(fp==0) return 0;

//跳过位图文件头结构BITMAPFILEHEADER fseek(fp, sizeof(BITMAPFILEHEADER),0);

//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中 BITMAPINFOHEADER head;

fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高、每像素所占位数等信息

bmpWidth = head.biWidth; bmpHeight = head.biHeight; biBitCount = head.biBitCount;

//定义变量,计算图像每行像素所占的字节数(必须是4的倍数) int lineByte=(bmpWidth * biBitCount/8+3)/4*4; //灰度图像有颜色表,且颜色表表项为256 if(biBitCount==8){

//申请颜色表所需要的空间,读颜色表进内存 pColorTable=new RGBQUAD[256];

fread(pColorTable,sizeof(RGBQUAD),256,fp); }

//申请位图数据所需要的空间,读位图数据进内存 pBmpBuf=new unsigned char[lineByte * bmpHeight]; fread(pBmpBuf,1,lineByte * bmpHeight,fp); //关闭文件 fclose(fp); return 1; }

2.BMP文件的存盘

给定图像路径名以及图像的数据,对图像的写操作也是按照BMP文件4个组成部分进行分别处理的。其基本流程如图1-9所示。

saveBmp()函数实现了BMP文件的写操作,该函数的说明及代码实现如下。

/***************************************** * 函数名称: * saveBmp() *

*函数参数:


VC++数字图像处理(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:妈妈十大寿祝寿词

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: