在界面中插入位图,主要用到BitBlt这个函数
BOOL CDC::BitBlt(int x, int y, int width, int height, CDC *src, int src_x, int src_y, DWORD dwRop)
用法说明见官方说明
这里要注意的是,这个函数是把源图像从src这个设备上下文传递到目标设备上下文(这个函数调用对象),源和目标的宽和高都是width, height,也就是不进行缩放。并且源的左上角(其实不一定真的是左上角,与实际使用的坐标系有关,指的是坐标最小的xy值)。
dwRop是操作码,操作码可以将官方说明,这里使用SRCCOPY。
另外要注意的是,如果width, height超过了源的大小,那么使用源的大小,width, height设置成源的大小。另外x, y, width, height可以超过目标的大小,比如x, y可以是小于0的数,如果超过了目标大小,超出的部分直接丢弃不显示,在目标区域的图像不受影响。
界面插入位图方法,除了这个BitBllt函数,还有其他几个函数需要使用
创建源的设备上下文无关
BOOL CDC::CreateCompatibleDC(CDC* pDC);
创建的这个设备上下文无关用于保存源图像,也就是上面BitBlt中的src这个CDC对象
导入图片
BOOL CBitmap::LoadBitmap(LPCTSTR sourcename)
BOOL CBitmap::LoadBitmap(UINT sourceID)
有两个方法可以使用,直接使用图片的路径,另一个先把图像放到资源文件中,然后用资源的id来导入
获取图片信息
int CBitmap::GetBitmap(BITMAP* pBitMap)
返回:非0为成功,0为不成功
BITMAP是一个结构体
/* Bitmap Header Definition */
typedef struct tagBITMAP{LONG bmType;LONG bmWidth;LONG bmHeight;LONG bmWidthBytes;WORD bmPlanes;WORD bmBitsPixel;LPVOID bmBits;} BITMAP
可以用这个函数获取图像的尺寸信息
有了以上这些函数,就可以在界面中插入位图了。下面是一个例子,直接在窗口客户区对象的OnDraw方法中调用
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);CBrush greenBrush;greenBrush.CreateSolidBrush(RGB(0, 255, 0));CBrush *pOldBrush = pDC->SelectObject(&greenBrush);pDC->Rectangle(&rect);pDC->SelectObject(pOldBrush);CDC picDC;//声明一个图片缓冲区picDC.CreateCompatibleDC(pDC);//创建一个与显示缓冲区兼容的内存缓冲区CBitmap NewBitmap,*pOldBitmap;NewBitmap.LoadBitmap(IDB_TEACUP);//从资源中导入位图BITMAP bmp;//声明bmp结构体NewBitmap.GetBitmap(&bmp);//获取位图信息 pOldBitmap=picDC.SelectObject(&NewBitmap);//将位图选入内存DCpicDC.SetMapMode(MM_ANISOTROPIC);//内存DC自定义坐标系picDC.SetWindowExt(bmp.bmWidth,bmp.bmHeight);picDC.SetViewportExt(bmp.bmWidth,-bmp.bmHeight);picDC.SetViewportOrg(bmp.bmWidth/2,bmp.bmHeight/2);int nX=rect.left+(rect.Width()-bmp.bmWidth)/2;//计算位图居中显示时的左下角点坐标int nY=rect.top+(rect.Height()-bmp.bmHeight)/2;pDC->BitBlt(nX,nY,bmp.bmWidth,bmp.bmHeight,&picDC,-bmp.bmWidth/2,-bmp.bmHeight/2,SRCCOPY);//图片拷贝到显示缓冲区//pDC->BitBlt(nX,nY,rect.Width(), rect.Height(),&picDC,-bmp.bmWidth/2,-bmp.bmHeight/2,SRCCOPY);//图片拷贝到显示缓冲区picDC.SelectObject(pOldBitmap);//恢复原位图NewBitmap.DeleteObject();//删除新位图picDC.DeleteDC();//删除picDC
效果如图
其中有一些函数比如SelectObject,SetMapMde之类的,这些在Windows图像编程中比较基础,可以看我另一篇文章:使用Windows GDI进行绘图