void CChap1_4View:: OnDataAccess () {
//获取文档类句柄
CChap1_4Doc* pDoc = GetDocument(); //如果DIB为空,则返回 if(pDoc->m_pDib==NULL) return;
//定义infoHead变量指向DIB中的BITMAPINFOHEADER结构
BITMAPINFOHEADER *infoHead=(BITMAPINFOHEADER*)pDoc->m_pDib; //获取DIB的宽、高、每像素所占位数 int width=infoHead->biWidth; int height=infoHead->biHeight; int biBitCount=infoHead->biBitCount; //每行像素所占字节数,必须是4的倍数 int lineByte=(width*biBitCount/8+3)/4*4;
//求颜色表的长度,彩色图像颜色表长度为0,非彩色图像(灰度图像) //颜色表长度为pow(2,biBitCount) int colorTableLng; if(biBitCount!=24)
colorTableLng=pow(2,biBitCount); else
colorTableLng=0;
//用pImgData指向DIB的位图数据起始位置
unsigned char* pImgData=(unsigned char*)(pDoc->m_pDib+ sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD) * colorTableLng); //以下将图像数据左下角1/4置成黑色 //循环变量,图像的坐标 int i, j;
if(biBitCount==8){//灰度图像 for(i=0;i else{//彩色图像 int k; for(i=0;i for(k=0;k<3;k++)//彩色图像,每像素三个分量都置0 *(pImgData+i*lineByte+j*3+k)=0; } } }//刷新显示 Invalidate(); } 图1-19所示是chap1_4应用程序运行的界面及数据访问的结果,其中图1-19(a)是运行界面,图1-19(b)是点击“数据访问”菜单的运行结果。 (a)chap1-4的运行界面 (b)点击“数据访问”菜单的结果 图1-19 chap1_4的运行界面 1.4.4 面向对象的DIB的读写及访问——ImgCenterDib类 上一节我们用面向过程的方式实现了图像的可视化编程,本节我们从另一个全新的角度——面向对象的方式实现图像的可视化编程。但是MFC中没有封装DIB类,我们可以自己完成。我们声明的类叫ImgCenterDib(Image Center DIB,取图像处理中心编写的DIB之意),里面封装了DIB位图处理所需要的基本的成员变量和成员函数。我们在后续章节的算法实现中都是以该类作为基类来派生的,这样既充分利用了面向对象程序设计的封装、继承等特性,又使得代码易于维护和移植。 1.ImgCenterDib类的定义 ImgCenterDib类的定义在头文件“ImageCenterDib.h”中,以下是该类的完整定义。 class ImgCenterDib { public: //图像数据指针 unsigned char * m_pImgData 1.ImgCenterDib类的定义 ImgCenterDib类的定义在头文件“ImageCenterDib.h”中,以下是该类的完整定义。 class ImgCenterDib { public: //图像数据指针 unsigned char * m_pImgData //图像颜色表指针 LPRGBQUAD m_lpColorTable; //每像素占的位数 int m_nBitCount; private: //指向DIB的指针(包含BITMAPFILEHEADER、BITMAPINFOHEADER和颜色表) LPBYTE m_lpDib; //图像信息头指针 LPBITMAPINFOHEADER m_lpBmpInfoHead; //调色板句柄 HPALETTE m_hPalette; //颜色表长度 int m_nColorTableLength; public: //不带参数的构造函数 ImgCenterDib(); //带参数的构造函数 ImgCenterDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData); //析构函数 ~ImgCenterDib(); //DIB读函数 BOOL Read(LPCTSTR lpszPathName); //DIB写函数 BOOL Write(LPCTSTR lpszPathName); //DIB显示函数 BOOL Draw(CDC* pDC, CPoint origin, CSize size); //逻辑调色板生成函数 void MakePalette(); //获取DIB的尺寸(宽、高) CSize GetDimensions(); //清理空间 void Empty(); //用新的数据替换当前DIB void ReplaceDib(CSize size, int nBitCount, LPRGBQUAD lpColorTable, unsigned char *pImgData); //计算颜色表的长度 int ComputeColorTabalLength(int nBitCount); protected: //图像的宽,像素为单位 int m_imgWidth; //图像的高,像素为单位 int m_imgHeight; }; 在该类的实现中,可以通过BMP文件读取的方式生成DIB,也可以通过参数传递的方式生成DIB,无论哪种方式,该类都是一次性为DIB的指针m_lpDib分配内存,这与1.4.3节对BMP文件的可视化编程(读写及访问)方式是一致的。 ImgCenterDib类的代码实现在文件“ImgCenterDib.cpp”中,下面分别讲述该类各成员函数的代码实现。 2.构造函数和析构函数 类的构造函数用来完成数据成员的初始化工作,系统在创建类的对象时自动调用构造函数。类的析构函数用来释放被分配的内存空间,当类的对象消失时系统自动调用该函数。以下是ImgCenterDib构造函数和析构函数的代码实现。 /*********************************************************************** * 函数名称: * ImgCenterDib() * *说明:无参数的构造函数,对成员变量进行初始化,创建一个对象 ***********************************************************************/ ImgCenterDib::ImgCenterDib() { m_lpDib=NULL;//初始化m_lpDib为空 m_lpColorTable=NULL;//颜色表指针为空 m_pImgData=NULL; //图像数据指针为空 m_lpBmpInfoHead=NULL; //图像信息头指针为空 m_hPalette = NULL;//调色板为空 }