首先,我们知道DDB位图是与设备相关的内存位图,在我们不需要建立很大的DDB位图时,可用CreateCompatibleBitmap函数,这个函数最大不能超过最多60MB。经过几天的学习和实践,我利用了CreateDIBSection函数进行位图的建立,居然可以建立大到50GB。当然这个是不现实的,因为太大了,要占用很大的存储空间。不过,经过这次的深入学习,我明白了图像一直很难懂的地方——实现的方法。
实践例子如下:
HBITMAP CPrintSetView::CreateBigBitmap(UINT nWidth, UINT nHeight)
{
CDC *pDC=GetDC();
CPalette *m_pal;
LPPALETTEENTRY pe=NULL;
BITMAPINFO bi;
BITMAPINFOHEADER biHeader;
RGBQUAD *pbmiColor=NULL;
BOOL bPal=TRUE;
int nNumEntries=0; //调色板颜色项目数
LPBYTE lpBits;
HBITMAP hBitmap; //DDB位图句柄
//当前显示系统是否支持调色板
if(!(pDC->GetDeviceCaps(RASTERCAPS)&RC_PALETTE))
{
bPal=FALSE; //不支持调色板
AfxMessageBox(_T("当前显系统不支持调色板!"));
}
biHeader.biSize=sizeof(BITMAPINFOHEADER);
biHeader.biWidth=(nWidth+31)/32; //4字节对齐
biHeader.biHeight=nHeight;
biHeader.biPlanes=pDC->GetDeviceCaps(PLANES); //获取调色板个数
biHeader.biBitCount=pDC->GetDeviceCaps(BITSPIXEL); //获取每像素位数
biHeader.biCompression=BI_RGB; //不压缩
biHeader.biSizeImage=0;
biHeader.biXPelsPerMeter=0;
biHeader.biYPelsPerMeter=0;
biHeader.biClrUsed=0;
biHeader.biClrImportant=0;
if(bPal) //支持调色板
{
m_pal=pDC->GetCurrentPalette(); //获取设备上下文调色板对象;
nNumEntries=m_pal->GetPaletteEntries(0,1<<pDC->GetDeviceCaps(BITSPIXEL),pe); //获取调色板项目
pbmiColor=new RGBQUAD[nNumEntries]; //分配内存
for(int i=0;i<nNumEntries;i++)
{
pbmiColor[i].rgbRed=pe[i].peRed;
pbmiColor[i].rgbGreen=pe[i].peGreen;
pbmiColor[i].rgbBlue=pe[i].peBlue;
}
bi.bmiColors[1]=pbmiColor[1];
}
else
{
//bi.bmiColors[0]=NULL;
}
bi.bmiHeader=biHeader;
lpBits=new BYTE[(biHeader.biWidth*biHeader.biHeight)>>3];
::memset(lpBits,0x070d,sizeof(lpBits)/sizeof(byte));
hBitmap=::CreateDIBSection(pDC->m_hDC,&bi,DIB_RGB_COLORS,(void**)&lpBits,NULL,NULL);
//delete lpBits; //不能删除,CreateDIBSection自己处理删除工作
delete pbmiColor;
return hBitmap;
}
//实现位图选入内存DC
void CPrintSetView::OnDraw(CDC* pDC)
{
CDC m_MemDC;
CBitmap bmp;
BITMAP bm;
bmp.Attach(CreateBigBitmap(78000,78000)); //大图片容量
m_MemDC.CreateCompatibleDC(pDC);
m_MemDC.SelectObject(static_cast<CBitmap *>(&bmp));
//在内存m_MemDC上绘制图像
//.......
//可以利用滚动视CScrollView来实现滚动
}