1.笔记
1.1位图的概念
位图是一种将显示器的图像数据不经过压缩而直接按位存储的文件格式,位图主要分为设备相关位图(device dependent bitmap,DDB),设备无关位图(device independent bitmap,DIB)。其中DIB以扩展名bmp留在文件中,DDB也称为GDI位图,是一种MFC内部位图格式,由BITMAP结构体描述。
显然导入MFC工程的DIB位图会转化为DDB位图,转存到BITMAP结构体。
1.2位图操作函数
1.2.1创建与指定设备上下文兼容的内存设备上下文函数
函数原型:
virtual BOOL CDC::CreateCompatibleDC(CDC* pDC);
pDC是显示设备上下文的指针,如果调用成功返回非零,否则返回零。
1.2.2导入位图函数
函数原型:
BOOL CBitmap::LoadBitmap(LPCTSTR lpszResourceName);
BOOL CBitmap::LoadBitmap(UNIT nIDResource);
lpszResourceName是指向包含位图资源名字的以NULL结尾字符串,nIDResource是位图资源的ID编号,调用成功返回非零,否则返回零。
1.2.3获取位图信息函数
函数原型:
int CBitmap::GetBitmap(BITMAP* pBitmap);
BITMAP定义了逻辑位图的宽度、高度、颜色格式、位图的字节数据。调用成功返回非零,否则返回零。
1.2.4位块传送函数
函数原型:
BOOL CDC::BitBlt(int x,int y,int nWidth,int nHeight,
CDC* pSrcDC,int xSrc,int ySrc,DWORD dwRop);
(x,y)是指定目标矩形区域坐标数值均最小的坐标,也称左上角逻辑坐标,nWidth和nHeight分别为目标矩形和源位图的宽度与高度(即(x+nWidth,y+nHeight)到达目标矩形对角线上另一端点),(xSrc,ySrc)是源位图左上角逻辑坐标,dwRop是光栅操作码,最常用的光栅操作码是SRCCOPY,表示将源位图直接拷贝到目标设备上下文中。调用成功返回非零,否则返回零。
1.2.5拉伸位图函数
如果目标矩形和源位图的大小不一致,就需要用到拉伸位图函数。
函数原型:
BOOL CDC::StretchBlt(int x,int y,int nWidth,int nHeight,
CDC* pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,
DWORD dwRop);
nSrcWidth和nSrcHeight是源位图的宽度和高度,其他参数含义同BitBlt。调用成功返回非零,否则返回零。
2.使用练习
2.1在客户区内显示一张位图。
void CExample1View::OnDraw(CDC* pDC)
{
CExample1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CRect rect;
GetClientRect(rect);
CDC memDC;
memDC.CreateCompatibleDC(pDC);//创建与显示设备上下文兼容的设备上下文
CBitmap newBitmap, * pOldBitmap;
newBitmap.LoadBitmapW(IDB_BITMAP1);//加载位图
pOldBitmap = memDC.SelectObject(&newBitmap);//导入位图并保存旧位图
pDC->BitBlt(0, 0, rect.Width(), rect.Height(),//拷贝位图到显示设备上下文
&memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOldBitmap);//恢复设备上下文
newBitmap.DeleteObject();//删除已经使用完的位图
memDC.DeleteDC();//删除已经使用完的设备上下文
}
2.2使用自定义坐标系显示一张位图,并且要将位图拉伸填满客户区。
void CExample1View::OnDraw(CDC* pDC)
{
CExample1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CRect rect;
GetClientRect(rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(rect.Width(), rect.Height());
pDC->SetViewportExt(rect.Width(), -rect.Height());
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
CDC memDC;
memDC.CreateCompatibleDC(pDC);//创建与显示设备上下文兼容的设备上下文
CBitmap newBitmap, * pOldBitmap;
newBitmap.LoadBitmapW(IDB_BITMAP1);//加载位图
BITMAP bmp;
newBitmap.GetBitmap(&bmp);//获得位图信息
pOldBitmap = memDC.SelectObject(&newBitmap);//导入位图并保存旧位图
memDC.SetMapMode(MM_ANISOTROPIC);//对导入位图的设备上下文进行建系
memDC.SetWindowExt(bmp.bmWidth, bmp.bmHeight);//使其与显示设备上下文的坐标系保持一致
memDC.SetViewportExt(bmp.bmWidth, -bmp.bmHeight);
memDC.SetViewportOrg(bmp.bmWidth / 2, bmp.bmHeight / 2);
//拷贝位图到显示设备上下文
pDC->StretchBlt(-rect.Width() / 2, -rect.Height() / 2, //等价于rect.left,rect.top
rect.Width(), rect.Height(),
&memDC, -bmp.bmWidth / 2, -bmp.bmHeight / 2,
bmp.bmWidth, bmp.bmHeight, SRCCOPY);
memDC.SelectObject(pOldBitmap);//恢复设备上下文
newBitmap.DeleteObject();//删除已经使用完的位图
memDC.DeleteDC();//删除已经使用完的设备上下文
}
实现效果为位图填满整个客户区,并且改变窗口大小位图跟着改变。