GDI对位图的绘制
2018-01-16 01:40
405 查看
位图的加载方式:
LoadBitmap:加载资源视图中的bmp图片
LoadImage:可以加载位图、图标、光标多种图像数据,既可以从资源视图中加载,也可以从磁盘中直接加载
如何理解DC以及如何将图片绘制到DC上?
我们将DC(设备)看成一个打印机,位图看成一个需要打印的A4纸,将我们要显示的过程看成打印机打印纸张的过程,打印的东西呈现在新的A4纸上,也就是实现了位图的绘制。当我们需要多次绘制时,类似多次打印纸张时,只需要再换一张纸张即可继续打印。
为什么要使用兼容DC?
因为Windows不允许直接将位图绘制到需要显示的窗口DC(设备上下文)上,只能将位图先放入兼容的设备上下文中(兼容DC),然后将兼容上下文的内容拷贝到设备上下文中,才能实现位图的绘制。
如何将兼容上下文的内容拷贝到设备上下文?
使用BitBlt或者StretchBlt两个API,它们实现的功能就是将兼容DC(源DC)中的内容拷贝目标DC(需要显示的DC)中。他们的区别是,BitBlt不能进行位图的缩放功能,而Stretch能实现缩放。
BitBlt
StretchBlt
示例:
绘制位图的步骤:
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);
示例源码
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绘制透明位图
- GDI C++(2) 位图的绘制
- Delphi GDI对象之绘制位图
- 使用C++绘制GDI位图的基本编写实例
- GDI之绘制位图
- GDI的 点 线 面 双缓冲 位图的绘制
- 【备忘】GDI位图绘制四部曲
- Delphi GDI对象之绘制位图
- GDI 总结二: 位图的绘制
- GDI 总结二: 位图的绘制
- GDI C++ 位图的绘制
- 转VC绘制位图--BeginPaint()与GetDC()的区别
- GDI位图透明显示
- 绘制位图的问题
- VML绘制油田井位图
- 使用GDI绘制直线
- 游戏编程入门(3):绘制基本 GDI 图形
- MFC-GDI绘制
- .Net学习笔记----2015-07-10(使用GDI绘制验证码)
- 第八章 象素、位图、字体和图象的绘制