设为首页 加入收藏

TOP

1.4.4 面向对象的DIB的读写及访问——ImgCenterDib类(1)
2013-10-07 00:21:53 来源: 作者: 【 】 浏览:72
Tags:1.4.4 面向 对象 DIB 读写 访问 ImgCenterDib

1.4.4  面向对象的DIB的读写及访问——ImgCenterDib类(1)

上一节我们用面向过程的方式实现了图像的可视化编程(www.cppentry.com),本节我们从另一个全新的角度——面向对象的方式实现图像的可视化编程(www.cppentry.com)。但是MFC中没有封装DIB类,我们可以自己完成。我们声明的类叫ImgCenterDib(Image Center DIB,取图像处理中心编写的DIB之意),里面封装了DIB位图处理所需要的基本的成员变量和成员函数。我们在后续章节的算法实现中都是以该类作为基类来派生的,这样既充分利用了面向对象程序设计的封装、继承等特性,又使得代码易于维护和移植。

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文件的可视化编程(www.cppentry.com)(读写及访问)方式是一致的。

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;//调色板为空
}
/****************************************
*******************************
* 函数名称:
*     ImgCenterDib()
*
*函数参数:
*    CSize size-图像大小(宽、高)
*    int nBitCount-每像素所占位数
*    LPRGBQUAD lpColorTable-颜色表指针
*    unsigned char *pImgData-位图数据指针
*
*返回值:
*    无
*
*说明:本函数为带参数的构造函数,给定位图的大小、
每像素位数、颜色表
*      及位图数据等信息,创建ImgCenterDib类的对象
********************************************
***************************/
ImgCenterDib::ImgCenterDib(CSize size, int
nBitCount, LPRGBQUAD lpColorTable,
unsigned char *pImgData)
{
//如果没有位图数据传入,我们认为是空的DIB,此时不分配DIB内存
if(pImgData==NULL){
m_lpDib=NULL;
m_lpColorTable=NULL;
m_pImgData=NULL;
m_lpBmpInfoHead=NULL;
m_hPalette = NULL;
}
else{//如果有位图数据传入
  //为图像的宽、高、每像素位数等成员变量赋值
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=nBitCount;
  //根据每像素位数,计算颜色表长度
m_nColorTableLength=ComputeColorTabalLength(nBitCount);
  //每行像素所占字节数,必须扩展成4的倍数
int lineByte=(m_imgWidth*nBitCount/8+3)/4*4;
  //位图数据缓冲区的大小(图像大小)
int imgBufSize=m_imgHeight*lineByte;
  //为m_lpDib一次性分配内存,生成DIB结构
m_lpDib=new BYTE [sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * m_nColorTableLength+imgBufSize];
  //填写BITMAPINFOHEADER结构
m_lpBmpInfoHead = (LPBITMAPINFOHEADER) m_lpDib;
m_lpBmpInfoHead->biSize = sizeof(BITMAPINFOHEADER);
m_lpBmpInfoHead->biWidth = m_imgWidth;
m_lpBmpInfoHead->biHeight = m_imgHeight;
m_lpBmpInfoHead->biPlanes = 1;
m_lpBmpInfoHead->biBitCount = m_nBitCount;
m_lpBmpInfoHead->biCompression = BI_RGB;
m_lpBmpInfoHead->biSizeImage = 0;
m_lpBmpInfoHead->biXPelsPerMeter = 0;
m_lpBmpInfoHead->biYPelsPerMeter = 0;
m_lpBmpInfoHead->biClrUsed = m_nColorTableLength;
m_lpBmpInfoHead->biClrImportant = m_nColorTableLength;
  //调色板句柄初始化为空,有颜色表时,MakePalette()
函数要创建新的逻辑调色板
m_hPalette = NULL;
if(m_nColorTableLength!=0){ //若有颜色表,
则将颜色表拷贝进DIB的颜色表位置
//用m_lpColorTable指向DIB颜色表的起始位置
m_lpColorTable=(LPRGBQUAD)(m_lpDib+sizeof
(BITMAPINFOHEADER));
   //颜色表拷贝
memcpy(m_lpColorTable,lpColorTable,
sizeof(RGBQUAD) * m_nColorTableLength);
   //创建逻辑调色板
MakePalette();
}
  //用m_pImgData指向DIB位图数据起始位置
m_pImgData = (LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD) * m_nColorTableLength;
  //拷贝图像数据进DIB位图数据区
memcpy(m_pImgData,pImgData,imgBufSize);
}
}
/**************************************
*********************************
* 函数名称:
*     ~ImgCenterDib()
*
*说明:析构函数,释放资源
************************************
***********************************/
ImgCenterDib::~ImgCenterDib()
{
//释放m_lpDib所指向的内存缓冲区
if(m_lpDib != NULL)
delete [] m_lpDib;
 //如果有调色板,释放调色板缓冲区
if(m_hPalette != NULL)
::DeleteObject(m_hPalette);
}
3.DIB的显示函数——Draw()
/**************************************
*********************************
* 函数名称:
*     Draw()
*
*函数参数:
*    CDC* pDC-设备环境指针
*    CPoint origin-显示矩形区域的左上角
*    CSize size-显示矩形区域的尺寸
*
*返回值:
*    0为失败,1为成功
*
*说明:给定设备环境指针,以及需要显示的矩形
区域在设备环境中的位置,
*      将m_lpDib所指向的DIB显示出来
****************************************
*******************************/
BOOL ImgCenterDib::Draw(CDC* pDC,
CPoint origin, CSize size)
{
//旧的调色板句柄
HPALETTE hOldPal=NULL;
 //如果DIB为空,则返回0
if(m_lpDib == NULL) return FALSE;
 //如果DIB有调色板
if(m_hPalette != NULL) {
//将调色板选进设备环境中
hOldPal=::SelectPalette(pDC->GetSafeHdc(),
m_hPalette, TRUE);
  //实现调色板
pDC->RealizePalette();
}
 //设置位图伸缩模式
pDC->SetStretchBltMode(COLORONCOLOR);
 //将DIB在pDC所指向的设备上进行显示
::StretchDIBits(pDC->GetSafeHdc(), origin.x,
origin.y, size.cx, size.cy,
0, 0, m_lpBmpInfoHead->biWidth,
m_lpBmpInfoHead->biHeight,m_pImgData,
(LPBITMAPINFO) m_lpBmpInfoHead,
DIB_RGB_COLORS, SRCCOPY);
 //恢复旧的调色板
if(hOldPal!=NULL)
::SelectPalette(pDC->GetSafeHdc(), hOldPal, TRUE);
 //函数返回
return TRUE;
}
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.4.4 面向对象的DIB的读写及访问.. 下一篇1.4.5 使用ImgCenterDib进行图像..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: