GDI,图像设备接口的简称。
首先介绍几个概念。
1、DC,设备上下文DeviceContext,也称为设备描述表。它是一个关于如何绘制图形的方法集合,既可以绘制各种图形,也可以确定在应用窗口中绘制图形的方式,即绘图模式和映射模式。Win32编程中使用HDC来标识。DC类似于画布,我们想要绘制图形首先就需要获得DC。
常见获得DC的方法
HDC hdc = ::GetDC(hwnd);
::ReleaseDC(hwnd,hdc);
此方法适合在窗口现有图形的基础上进行绘制。(获得DC后一定要记得Release,否则会造成内存泄漏)
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(hWnd,&ps);
::EndPaint(hWnd,&ps);
BeginPaint函数就是将窗口上所有内容清除干净,然后在上面绘制。参数ps可以指定更新的区域,而不必重绘制整个界面, BeginPaint和EndPaint总是被用来响应WM_PAINT消息。
HDC hMemDC = ::CreateCompatibleDC(hDest);
//其他绘图操作代码
::BitBlt(hDest,x,y,w,h,hMemDC,0,0,SRCCOPY);//将hMemDC上绘制的图像数据拷贝到hDest上,界面此时才会显示
::DeleteDC(hMemDC);
通过调用CreateCompatibleDC函数来创建与目标DC兼容的内存DC,一般用于解决界面的闪烁问题。
2、常用的GDI对象
画笔Pen:负责画线,画边框(矩形边框,圆边框,饼边框)都是采用画笔来操作的。默认画笔是黑色,宽度为1,样式为实线的画笔。
画刷Brush:负责填充矩形,填充圆、饼等以及刷窗口背景。默认为白色画刷。
字体Font:负责基于具体字体对象的所有的文本绘制,默认字体是系统等宽字体,比如对话框标题。
区域Region:用HRGN表示,在窗口中一个区域可以是椭圆形,多边形或者更常见的矩形。
位图Bitmap:在GDI中,用HBITMAP来表示位图,GDI的绘制从答题上可以分为图形绘制和图像绘制。对于线,矩形,圆,饼等的绘制属于图形绘制,而对于位图的绘制是属于图像绘制。
3、使用GDI对象
SelectObject函数,选择使用的GDI对象
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj)
hdc:设备上下文环境的句柄。
hgdiobj:被选择的对象的句柄,该指定对象必须由如下的函数创建。
返回值:返回该DC对象的老的相同类型的GDI对象。
HGDIOBJ GetStockObject(int i),获得默认的GDI对象
通过ID号来获得windows默认提供的一些GDI对象。ID号为预定义的宏,这些对象获得后,不需要人为的销毁。
//字体
#define OEM_FIXED_FONT 10
#define ANSI_FIXED_FONT 11
…
//画刷
#define WHITE_BRUSH 0
…
//画笔
#define WHITE_PEN 6
…
GetObject函数,获取GDI对象的信息
int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
第一个参数填入GDI对象的句柄;
第二个参数填入结构的大小;
第三个参数填入结构的指针,这里的结构对应相应的GDI对象的结构。
DeleteObject函数,删除GDI对象。
创建的GDI对象一定要删除,否则会造成内存泄漏。
4、绘制位图的步骤
获得目标DC句柄
创建与目标DC兼容的临时内存DC
将位图句柄选入到临时内存DC中
使用BitBlt函数将临时内存DC中的位图拷贝到目标DC上来
将位图句柄选出临时内存DC
销毁临时的内存DC
注意:一定要将位图句柄选出临时内存DC,否则目标DC被拷贝的位图也会被销毁掉。
下面是用到的函数
加载BitMap图片
HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);
从应用程序资源中读取位图数据,所以使用这个接口时,我们需要先将位图导入资源中。第一个参数传入资源所在的模块实例句柄,第二参数是位图在资源中的ID名称。
HBITMAP hbmp = LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BACK));
宏MAKEINTRESOURCE将数字的ID号转换成整形资源号字符串。
LoadBitmap已经被LoadImage函数取代了。
LoadImage函数可以加载位图、图标、光标等多种图像数据。
既可以从资源加载:
HBITMAP hbmp = (HBITMAP)::LoadImage(hInstance, MAKEINTRESOURCE(IDB_BACK)
,IMAGE_BITMAP,0,0,LR_CREATEDDIBSECTION|LR_LOADMAP3DCOLORS);
或者直接从路径加载:
HBITMAP hbmp = (HBITMAP)::LoadImage(NULL, _T(“.\1.bmp”),IMAGE_BITMAP,0,0,
LR_LOADFORMFILE|LR_DEFAULTSIZE| LR_LOADMAP3DCOLORS);
BitBlt绘制位图函数。
BOOL BitBlt( _In_ HDC hdcDest, _In_ int nXDest, _In_ int nYDest, _In_ int nWidth, _In_ int nHeight, _In_ HDC hdcSrc, _In_ int nXSrc, _In_ int nYSrc, _In_ DWORD dwRop);
hDestDC:指向目标设备环境的句柄。
x:指定目标矩形区域左上角的X轴逻辑坐标。
y:指定目标矩形区域左上角的Y轴逻辑坐标。
nWidth:指定源在目标矩形区域的逻辑宽度。
nHeight:指定源在目标矩形区域的逻辑高度。
hSrcDC:指向源设备环境的句柄。
xSrc:指定源矩形区域左上角的X轴逻辑坐标。
ySrc:指定源矩形区域左上角的Y轴逻辑坐标。
dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。一般SRCCOPY是拷贝的意思。
HDC hDCmem = ::CreateCompatibleDC(hdc);
HBITMap hOldBmp = (HBITMap)::SelectObject(hDCmem,hbmpBack);
BITMAP bmp;
::GetObject(hbmpBack,sizeof(BITMAP),&bmp);
::BitBlt(hdc,0,0,bmp.bmWidth,bmp.bmHeight,HDCmem,0,0,SRCCOPY);
//绘图
::SelectObject(hDCmem,hOldBmp);
::DeleteDC(hDCmem);
拉伸图片
GetClientRect函数获得客户区大小
使用StretchBlt函数对图片进行拉伸
5、文字绘制
指定字体的大小编码的结构体LOGFONT
设置文字的颜色GetTextColor
获得文字的颜色SetTextColor
设置背景模式SetBKMode,设置DC的背景模式,相对应的GetBKMode是用来获取背景模式的。mode参数可以是TRANSPARENT(透明)与OPAQUE(不透明,默认值)
DrawText函数和TextOut函数都是绘制文字的函数,前者通过控制绘制区域和绘制格式来控制绘制的位置,后者可以直接指定绘制的起始位置和结束位置。
6、绘制点,线,面
SetPixel/GetPixel设置/返回指定点的颜色。
MoveToEx设置线的绘制起点
LineTo绘制线
Rectangle采用选定的画笔和画刷来绘制矩形。画笔负责绘制矩形的边框,画刷负责填充矩形。
Ellipse绘制圆,需要指定这个圆的外接矩形。
Pie绘制扇形图
GDI+的介绍
GDI+是windows系统中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需要调用GDI+库输出的类的一些方法即可完成图形操作。
GDI+的使用方法
在使用GDI+的cpp文件中包含GdiPlus.h的头文件,并引用命名空间using namespace Gdiplus。
同时需要在项目属性中的连接器->输入->附加依赖项中加入gdiplus.lib。
同时需要在主程序的开始部分,添加如下代码:
//GDI+资源初始化
ULONG_PTR uToken = 0;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&uToKen,&gdiplusStartupInput,NULL);
应用程序结束时,需要销毁GDI+资源
GdiplusShutdown(uToken);
GDI+系统中的透明度的概念
透明度是像素之间的一种合成运算,它的计算公式是:
输出颜色=前景色*Alpha/255 + 背景色*(255-Alpha)/255;
GDI+常用的几个类。
Graphics类,类似于GDI中DC。
Bitmap类,继承与Image类。
GDI+中使用Graphics类的DrawImage函数来绘制图片。
使用Graphics类measureString函数来测量字符串的需要容纳的矩形区域。
DrawLine/DrawRectangle/DrawEllipse/DrawPie画图
GDI+中的核心是Graphics类而GDI中是基于DC句柄的。
GDI+在GDI的设备环境DC上进行图形的绘制。GDI+就回吧当前的DC作为默认的目标画布,之后调用Graphics中的任何函数都会被绘制到DC对象上,当然每个函数的调用完成并不会立即反映到DC中,只有当Graphics类析构的时候才会把所有绘制的内容全部一次性地拷贝到hDC中。
Graphics提供了获得HDC的函数GetHDC,这样我们就可以在hDC上进行GDI函数的绘制。