程序返回内存设备的对象,pDC是设备兼容的对象(CreateCompatibleDC(pDC);需要这个参数)
pwidth用于接收图片的实际宽度,pheight接收高
对于返回的CDC使用bitblt来绘制,本代码是用MFC写的,
如果你懂MFC那最好,注意使用完记得调用FreeBmp释放内存
代码这么多其实主要是考虑到错误处理,真正操作图片的代码就不多,就是读取文件数据然后调用CreateDIBitmap再seleteobject而已
CDC*LoadBmp(CString fileName,CDC*pDC,int *pwidth,int *pheight){
CFile cf;//文件变量,用来对文件操作
CFileException e;//出错处理
BITMAPFILEHEADER bmfh;//BMP文件头变量
BITMAPINFOHEADER bmih;//BMP文件信息变量
BYTE *pData;//原始数据
CDC *pMem;//内存设备
HBITMAP hBitmap;//位图
int n;//图象数据中BYTE的个数
int width;//4倍对齐后的宽
if (!cf.Open(fileName,CFile::modeRead, &e))//找到文件后,打开文件
{
MessageBox(NULL,"文件被其他程序占用了","",MB_OK);
return NULL;
}
cf.SeekToBegin();
cf.Read(&bmfh,sizeof(bmfh));//读取文件头
cf.Read(&bmih,sizeof(bmih));//读取文件信息头
if(bmfh.bfType!=0x4d42)
{
MessageBox(NULL,"文件格式错误","",MB_OK);
cf.Close();
return NULL;
}
if(bmih.biCompression!=BI_RGB)//BI_RGBD的非压缩格式
{
MessageBox(NULL,"文件需要解压","",MB_OK);
cf.Close();
return NULL;
}
width=(bmih.biWidth*4+3)/4;//4对齐
n=bmih.biHeight*width*bmih.biBitCount/8+bmfh.bfOffBits-sizeof(BITMAPFILEHEADER);//计算数据字节数其中包括位图信息头
pData=new BYTE[n];//为数据分配空间
if(!pData)
{
MessageBox(NULL,"内存不足","",MB_OK);
cf.Close();
return NULL;
}
pMem = new CDC;//创建内存设备
if(!pMem)
{
MessageBox(NULL,"内存不足","",MB_OK);
cf.Close();
delete [] pData;
return NULL;
}
pMem->CreateCompatibleDC(pDC);//创建内存设备
cf.SeekToBegin();
cf.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
cf.Read(pData,n);//读取数据
hBitmap=CreateDIBitmap(pDC->m_hDC,&bmih,CBM_INIT,pData+bmfh.bfOffBits-sizeof(BITMAPFILEHEADER),
(LPBITMAPINFO)pData,DIB_RGB_COLORS);//如创建一个屏幕大小的bitmap,这个函数将自动绘制图片
pMem->SelectObject(hBitmap);//选择内存设备,图象将绘制在pMem上
cf.Close();//关闭文件
delete [] pData;
DeleteObject(hBitmap);
if(pwidth)
*pwidth=bmih.biWidth;
if(pheight)
*pheight=bmih.biHeight;
return pMem;
}
void FreeBmp(CDC*&pMem)
{
if(!pMem) return;
DeleteDC(pMem->m_hDC);//释放内存设备
delete pMem;
pMem=NULL;
}
[
本帖最后由 faminxmu 于 2010-6-17 20:12 编辑 ]