您的位置:首页 > 其它

GDI对位图的绘制

2018-01-16 01:40 405 查看
位图的加载方式:

LoadBitmap:加载资源视图中的bmp图片

HBITMAP LoadBitmap(
HINSTANCE hInstance,
LPCTSTR lpBitmapName
);


LoadImage:可以加载位图、图标、光标多种图像数据,既可以从资源视图中加载,也可以从磁盘中直接加载

HANDLE LoadImage(
HINSTANCE hinst,
LPCTSTR lpszName,
UINT uType, // 类型:位图、图标、光标
int cxDesired,
int cyDesired,
UINT fuLoad
);


如何理解DC以及如何将图片绘制到DC上?

我们将DC(设备)看成一个打印机,位图看成一个需要打印的A4纸,将我们要显示的过程看成打印机打印纸张的过程,打印的东西呈现在新的A4纸上,也就是实现了位图的绘制。当我们需要多次绘制时,类似多次打印纸张时,只需要再换一张纸张即可继续打印。

为什么要使用兼容DC?

因为Windows不允许直接将位图绘制到需要显示的窗口DC(设备上下文)上,只能将位图先放入兼容的设备上下文中(兼容DC),然后将兼容上下文的内容拷贝到设备上下文中,才能实现位图的绘制。

如何将兼容上下文的内容拷贝到设备上下文?

使用BitBlt或者StretchBlt两个API,它们实现的功能就是将兼容DC(源DC)中的内容拷贝目标DC(需要显示的DC)中。他们的区别是,BitBlt不能进行位图的缩放功能,而Stretch能实现缩放。

BitBlt

BOOL BitBlt(
HDC hdcDest, // 目标DC句柄
int nXDest, int nYDest, int nWidth, int nHeight, // 目标区域
HDC hdcSrc, // 源DC句柄
int nXSrc, int nYSrc, //源区域的左上角
DWORD dwRop // 操作的方式,一般为SRCCOPY(拷贝)
);


StretchBlt

BOOL StretchBlt(
HDC hdcDest,    //目标DC的句柄
int xDest, int yDest, int wDest, int hDest,     //目标DC的区域
HDC hdcSrc,     //源DC的句柄
int xSrc, int ySrc, int wSrc, __in int hSrc,    //源DC的区域
DWORD rop      //操作标志,一般为SRCCOPY,意思为拷贝
);


示例:

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...

HDC hMemDC = ::CreateCompatibleDC(hdc);
HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, g_hBmpBack);
BITMAP bmp;
::GetObject(g_hBmpBack, sizeof(BITMAP), &bmp);
::BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);
/*RECT rc;
::GetClientRect(hWnd, &rc);
int nWidth = rc.right - rc.left;
int nHeight = rc.bottom - rc.top;
::StretchBlt(hdc, 0, 0, nWidth, nHeight, hMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);*/

::SelectObject(hMemDC, hOldBmp);
::DeleteDC(hMemDC);

EndPaint(hWnd, &ps);
}
break;


绘制位图的步骤:

1)获得目标DC句柄

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

2)创建与目标DC兼容的临时内存DC

HDC hMemDC = ::CreateCompatibleDC(hdc);

3)将位图句柄选入到临时内存DC中

HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, g_hBmpBack);

4)使用BitBlt函数将临时内存DC中的位图拷贝到目标DC上来

BITMAP bmp;

::GetObject(g_hBmpBack, sizeof(BITMAP), &bmp);//根据位图句柄获取到位图的数据到bmp中

::BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, hMemDC, 0, 0, SRCCOPY);

5)将现在的位图句柄选出临时内存DC,也就是将我们原来的位图句柄选入内存DC中。这里为什么需要选出来?如果不选出来,当前的位图句柄还在内存DC中,使用DeleteDC后将会同时删除现在使用的位图句柄。

::SelectObject(hMemDC, hOldBmp);

6)销毁临时的内存DC

::DeleteDC(hMemDC);

7)结束绘制

EndPaint(hWnd, &ps);

示例源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gdi 位图