您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > 在VC++中如何将绘制的图形存储成位图
在VC++中如何将绘制的图形存储成位图太匆匆忙2009-12-1614:19:04124.164.196.*您好CClientDCdc(this);//取得客户区内存DCCDCTHDC;HBITMAPTHBM;THDC.CreateCompatibleDC(0);//创建相关场景THBM=(HBITMAP)LoadImage(NULL,D:\\x.bmp,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);//载入位图BITMAPbmp;GetObject(THBM,sizeof(bmp),&bmp);//取得位图信息SelectObject(THDC,THBM);//选入位图至内存DCDeleteObject(THBM);//删除位图BitBlt(dc,0,0,bmp.bmWidth,bmp.bmHeight,THDC,0,0,SRCCOPY);//将临时内存DC中的位图画到客户区中//首先在D盘根目录下放一个标准.bmp格式的位图再将这些代码写入一个按钮事件中点击按键就会在窗体的左上角看到图形了.calpt2009-12-2618:03:43116.205.254.* VisualC++MFC中没有提供一个专门的类来处理DIB位图,因此,为了方便地使用位图文件,我们有必要派生一个CDib类。类的源代码如下: (1)CDib类的声明//DIB.h:类CDib声明头文件#ifndef__DIB_H__#define__DIB_H__#include<wingdi.h>classCDib{ public: CDib(); ~CDib(); BOOLLoad(constchar*); BOOLSave(constchar*); BOOLDraw(CDC*,intnX=0,intnY=0,intnWidth=-1,intnHeight=-1,intmode=SRCCOPY); BOOLSetPalette(CDC*); private: CPalettem_Palette; unsignedchar*m_pDib,*m_pDibBits; DWORDm_dwDibSize; BITMAPINFOHEADER*m_pBIH; RGBQUAD*m_pPalette; intm_nPaletteEntries;};#endif (2)CDib类的实现//DIB.cpp:类CDib实现文件#include"stdafx.h"#include"DIB.h"CDib::CDib(){ m_pDib=NULL;}CDib::~CDib(){ //如果位图已经被加载,释放内存 if(m_pDib!=NULL) delete[]m_pDib;} 下面这个函数非常重要,其功能为加载位图,类似于CBitmap类的LoadBitmap函数:BOOLCDib::Load(constchar*pszFilename){ CFilecf; //打开位图文件 if(!cf.Open(pszFilename,CFile::modeRead)) return(FALSE); //获得位图文件大小,并减去BITMAPFILEHEADER的长度 DWORDdwDibSize; dwDibSize=cf.GetLength()-sizeof(BITMAPFILEHEADER); //为DIB位图分配内存 unsignedchar*pDib; pDib=newunsignedchar[dwDibSize]; if(pDib==NULL) return(FALSE); BITMAPFILEHEADERBFH; //读取位图文件数据 try { //文件格式是否正确有效 if(cf.Read(&BFH,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER)|| BFH.bfType!=’MB’||cf.Read(pDib,dwDibSize)!=dwDibSize) { delete[]pDib; return(FALSE); } } catch(CFileException*e) { e->Delete(); delete[]pDib; return(FALSE); } //delete先前加载的位图 if(m_pDib!=NULL) deletem_pDib; //将临时Dib数据指针和Dib大小变量赋给类成员变量 m_pDib=pDib; m_dwDibSize=dwDibSize; //为相应类成员变量赋BITMAPINFOHEADER和调色板指针 m_pBIH=(BITMAPINFOHEADER*)m_pDib; m_pPalette=(RGBQUAD*)&m_pDib[sizeof(BITMAPINFOHEADER)]; //计算调色板中实际颜色数量 m_nPaletteEntries=1<<m_pBIH->biBitCount; if(m_pBIH->biBitCount>8) m_nPaletteEntries=0; elseif(m_pBIH->biClrUsed!=0) m_nPaletteEntries=m_pBIH->biClrUsed; //为相应类成员变量赋imagedata指针 m_pDibBits=&m_pDib[sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD)]; //delete先前的调色板 if(m_Palette.GetSafeHandle()!=NULL) m_Palette.DeleteObject(); //如果位图中存在调色板,创建LOGPALETTE及CPalette if(m_nPaletteEntries!=0) { LOGPALETTE*pLogPal=(LOGPALETTE*)newchar[sizeof(LOGPALETTE)+m_nPaletteEntries*sizeof(PALETTEENTRY)]; if(pLogPal!=NULL) { pLogPal->palVersion=0x300; pLogPal->palNumEntries=m_nPaletteEntries; for(inti=0;i<m_nPaletteEntries;i++) { pLogPal->palPalEntry[i].peRed=m_pPalette[i].rgbRed; pLogPal->palPalEntry[i].peGreen=m_pPalette[i].rgbGreen; pLogPal->palPalEntry[i].peBlue=m_pPalette[i].rgbBlue; } //创建CPalette并释放LOGPALETTE的内存 m_Palette.CreatePalette(pLogPal); delete[]pLogPal; } } return(TRUE);}//函数功能:保存位图入BMP文件BOOLCDib::Save(constchar*pszFilename){ if(m_pDib==NULL) return(FALSE); CFilecf; if(!cf.Open(pszFilename,CFile::modeCreate|CFile::modeWrite)) return(FALSE); try { BITMAPFILEHEADERBFH; memset(&BFH,0,sizeof(BITMAPFILEHEADER)); BFH.bfType=’MB’; BFH.bfSize=sizeof(BITMAPFILEHEADER)+m_dwDibSize; BFH.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD); cf.Write(&BFH,sizeof(BITMAPFILEHEADER)); cf.Write(m_pDib,m_dwDibSize); } catch(CFileException*e) { e->Delete(); return(FALSE); } return(TRUE);} 下面这个函数也非常重要,其功能为在pDC指向的CDC中绘制位图,起点坐标为(nX,nY),绘制宽度和高度为nWidth、nHeight,最后一个参数是光栅模式:BOOLCDib::Draw(CDC*pDC,intnX,intnY,intnWidth,intnHeight,intmode){ if(m_pDib==NULL) return(FALSE); //获取位图宽度和高度赋值 if(nWidth==-1) nWidth=m_pBIH->biWidth; if(nHeight==-1) nHeight=m_pBIH->biHeight; //绘制位图 StretchDIBits(pDC->m_hDC,nX,nY,nWidth,nHeight,0,0,m_pBIH->biWidth,m_pBIH->biHeight,m_pDibBits,(BITMAPINFO*)m_pBIH,BI_RGB,mode); return(TRUE);}//函数功能:设置调色板BOOLCDib::SetPalette(CDC*pDC){ if(m_pDib==NULL) return(FALSE); //检查当前是否有一个调色板句柄,对于大于256色的位图,为NULL if(m_Palette.GetSafeHandle()==NULL) return(TRUE); //选择调色板,接着实施之,最后恢复老的调色板 CPalette*pOldPalette; pOldPalette=pDC->SelectPalette(&m_Palette,FALSE); pDC->RealizePalette(); pDC->SelectPalette(pOldPalette,FALSE); return(TRUE);} 从整个CDib类的代码中我们可以看出,DIB位图的显示需遵循如下步骤: (1)读取位图,本类中使用pDib=newunsignedchar[dwDibSize]为位图中的信息分配内存,另一种方法是调用API函数CreateDIBSection,譬如:m_hBitmap=::CreateDIBSection(pDC->GetSafeHdc(),(LPBITMAPINFO)m_lpBMPHdr,DIB_RGB_COLORS,(LPVOID*)&m_lpDIBits,NULL,0); m_hBitmap定义为:HBITMAPm_hBitmap; (2)根据读取的位图信息,计算出调色板大小,然后创建调色板; (3)调用CDib::SetPalette(CDC*pDC)设置调色板,需要用到CDC::SelectPalette及CDC::RealizePalette两个函数; (4)调用CDib::Draw(CDC*pDC,intnX,intnY,intnWidth,intnHeight,intmode)函数绘制位图。在此函数中,真正发挥显示位图作用的是对StretchDIBitsAPI函数的调用。StretchDIBits函数具有缩放功能,其最后一个参数也是光栅操作的模式。 下面给出DIB位图的打开及显示并在其中加入天极网logo的函数源代码。&q
本文标题:在VC++中如何将绘制的图形存储成位图
链接地址:https://www.777doc.com/doc-5102946 .html