三、 图像的显示
显示DIB位图数据可以通过设备上下文CDC对象的成员函数CDC::Bitblt()或CDC::StretchBlt()来实现,也可以通过API函数SetDIBBitsToDevice()或StretchDIBBits()来实现,函数中具体所用到的各个参数的意义可以参考MSDN。其中StretchDIBBits()和CDC::StretchBlt()可以将图像进行放大和缩小显示。当从文档中装入位图文件时,CDIBView类的OnInitialUpdate函数将被调用,因此可以在该函数中实现对视图尺寸的设置,用于正确的显示位图,然后就可以在视图类的OnDraw()函数中正确的显示位图了。这两个函数的具体实现代码分别如下所示:
///////////////////////////////////////////////////////////// void CDIBView::OnInitialUpdate() { CscrollView::OnInitalUpdate(); CDIBDoc *pDoc=GetDocument(); If(pDoc->m_hDIB==NULL)//如果位图数据为空,设置m_sizeDoc的默认尺寸; pDoc->m_sizeDoc.cx=pDoc->m_sizeDoc.cy=100; SetScrollSizes(MM_TEXT,pDoc-> m_sizeDoc); } ///////////////////////////////////////////////////////////// void CDIBView::OnDraw(CDC *pDC) { BITMAPINFOHEADER *lpDIBHdr;//位图信息头结构指针; BYTE *lpDIBBits;//指向位图像素灰度值的指针; BOOL bSuccess=FALSE; CPalette*OldPal=NULL;//调色板指针; HDC hDC=pDC->GetSafeHdc();//获取当前设备上下文的句柄; CDIBDoc *pDoc=GetDocument();//获取活动文档的指针; If(pDoc->m_hDIB ==NULL) {//判断图像数据是否为空; AfxMessageBox("图像数据不能为空,请首先读取图像数据!"); return; } lpDIBHdr=( BITMAPINFOHEADER *)GlobalLock(pDoc->m_hDIB);//得到图像的位图头信息 lpDIBBits=lpDIBHdr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);//获取保存图像像素值的缓冲区的指针; if(pDoc-> m_palDIB) {//如果存在调色板信息,实现逻辑调色板; OldPal=pDC-> SelectPalette(pDoc-> m_palDIB,TRUE); PDC->RealizePalette(); } else { AfxMessageBox("图像的调色板数据不能为空,请首先读取调色板信息!"); return ; } SetStretchBltMode(hDC,COLORONCOLOR); //显示图像 BSuccess=StretchDIBBits(hDC,0,0,pDoc-> m_sizeDoc.cx, pDoc-> m_sizeDoc.cy, 0, pDoc-> m_sizeDoc.cy,0, pDoc-> m_sizeDoc.cy, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); GlobalUnlock(pDoc->m_hDIB); If(OldPal)//恢复调色板; PDC->SelectPalette(OldPal,FALSE); retrun; }
|
四、 小结
在本期讲座里我们主要介绍了如何操作灰度位图,它具有较强的代表性,同时为后续的图像处理编程(www.cppentry.com)的学习作了必要的准备工作,经过学习,对于如何操作其它类型的BMP格式的图像文件,可以达到举一反三的作用。 |