归纳可得,利用GDI进行图形、图像处理的一般操作步骤为:
1. 取得指定窗口的DC;
2. 确定使用的坐标系及映射方式;
3. 进行图形、图像或文字处理;
4. 释放所使用的DC。
4.GDI+编程
"GDI+"菜单下的"画线"子菜单单击事件消息处理函数的代码如下:
void CGdiexampleDlg::OnGdipDrawLine()
{
// TODO: Add your command handler code here
CClientDC dc(this);
//逻辑坐标与设备坐标变换
CRect rect;
GetClientRect(&rect);
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetWindowOrg(0, 0);
dc.SetWindowExt(rect.right, rect.bottom);
dc.SetViewportOrg(0, rect.bottom / 2);
dc.SetViewportExt(rect.right, - rect.bottom);
//创建Graphics对象
Graphics graphics(dc);
//创建pen
Pen myPen(Color::Red);
myPen.SetWidth(1);
//画正旋曲线
for (int i = 0; i < rect.right; i++)
{
graphics.DrawLine(&myPen, i, 100 *sin(2 *(i / (rect.right / 5.0)) *PI), i +
1, 100 *sin(2 *((i + 1) / (rect.right / 5.0)) *PI));
}
//画X轴
myPen.SetColor(Color::Blue);
graphics.DrawLine(&myPen, 0, 0, rect.right, 0);
}
由于我们使用的是Visual C++6.0而非VS.Net,我们需要下载微软的GDIPLUS支持包。在微软官方网站下载时需认证Windows为正版,我们可从这个地址下载:。一个完整的GDI+支持包至少包括如下文件:
(1)头文件:gdiplus.h
(2)动态链接库的.lib文件:gdiplus.lib
(3)动态链接库的.dll文件:gdiplus.dll
少了(1)、(2)程序不能编译,少了(3)程序能以共享DLL的方式编译但是不能运行,运行时找不到.dll文件。
为使得Visual C++6.0支持GDI+,我们需要在使用GDI+对象的文件的开头添加如下代码:
#define UNICODE
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include "c:\gdiplus\includes\gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "c:\\gdiplus\\lib\\gdiplus.lib")
在Visual C++中使用GDI+必须先进行GDI+的初始化,我们在CWinApp派生类的InitInstance函数中进行此项工作是{zh0}的:
/////////////////////////////////////////////////////////////////////////////
// CGdiexampleApp initialization
BOOL CGdiexampleApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
//初始化gdiplus的环境
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// 初始化GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CGdiexampleDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK){}
else if (nResponse == IDCANCEL){}
//关闭gdiplus的环境
GdiplusShutdown(gdiplusToken);
return FALSE;
}
单击"GDI+"菜单下的"画线"子菜单,也会出现如图1所示的效果。观察void CGdiexampleDlg::OnGdipDrawLine() 函数,我们发现用GDI+进行图形、图像操作的步骤为:
(1)创建 Graphics 对象:Graphics 对象表示GDI+绘图表面,是用于创建图形图像的对象;
(2)使用 Graphics 对象绘制线条和形状、呈现文本或显示与操作图像。
Graphics 对象是GDI+的核心,GDI中设备上下文dc和Graphics 对象的作用相似,但在GDI中使用的是基于句柄的编程模式,而GDI+中使用的则是基于对象的编程模式。Graphics封装了GDI+ 绘图面,而且此类无法被继承,它的所有成员函数都不是虚函数。
下面,我们来逐个用实际代码实现GDI+的新增功能,这些新增功能包括:渐变的画刷(Gradient Brushes)、基数样条函数(Cardinal Splines)、持久的路径对象(Persistent Path Objects)、变形和矩阵对象(Transformations &Matrix Object)、可伸缩区域(Scalable Regions)、Alpha混合(Alpha Blending)和丰富的图像格式支持等。
渐变的画刷
GDI+提供了用于填充图形、路径和区域的线性渐变画刷和路径渐变画刷。
线性渐变画刷使用渐变颜色来填充图形。
当用路径渐变画刷填充图形时,可指定从图形的一部分移至另一部分时画刷颜色的变化方式。例如,我们可以只指定图形的中心颜色和边缘颜色,当画刷从图形中间向外边缘移动时,画刷会逐渐从中心颜色变化到边缘颜色。
void CGdiexampleDlg::OnGradientBrush()
{
// TODO: Add your command handler code here
CClientDC dc(this);
CRect rect;
GetClientRect(&rect);
//创建Graphics对象
Graphics graphics(dc);
//创建渐变画刷
LinearGradientBrush lgb(Point(0, 0), Point(rect.right, rect.bottom), Color::Blue, Color::Green);
//填充
graphics.FillRectangle(&lgb, 0, 0, rect.right, rect.bottom);
}
本程序使用线性渐变画刷,当画刷从客户区左上角移向客户区右下角的过程中,颜色逐渐由蓝色转变为绿色。
图3 GDI+渐变画刷
基数样条函数
GDI+支持基数样条,基数样条指的是一连串单独的曲线,这些曲线连接起来形成一条较大的曲线。样条由点(Point结构体)的数组指定,并通过该数组中的每一个点。基数样条平滑地穿过数组中的每一个点(不出现尖角),因此比用直线连接创建的路径xx。
void CGdiexampleDlg::OnCardinalSpline()
{
// TODO: Add your command handler code here
CClientDC dc(this);
//创建Graphics对象
Graphics graphics(dc);
Point points[] =
{
Point(0, 0), Point(100, 200), Point(200, 0), Point(300, 200), Point(400, 00)
};
//直接画线
for (int i = 0; i < 4; i++)
{
graphics.DrawLine(&Pen(Color::Blue, 3), points[i], points[i + 1]);
}
//利用基数样条画线
graphics.DrawCurve(&Pen(Color::Red, 3), points, 5);
}
图4演示了直接连线和经过基数样条平滑拟合后的线条的对比,后者的曲线(Curve)没有尖角。这个工作我们在中学的数学课上把离散的点连接成曲线时做过。
图4 GDI+基数样条
本文来自CSDN博客,转载请标明出处: