本文为GDI+ for VCL基础系列文章之一,主要供GDI+初学者入门参考,例子使用GDI+版本下载地址和说明见《GDI+ for VCL基础 -- GDI+ 与 VCL》。如有错误或者建议请来信:maozefa@hotmail.com
GDI+ 提供了很多绘图方法,如直线、曲线、圆弧、矩形、椭圆、扇形、多边形以及路径线条等,这些图形都需要使用GDI+ 画笔对象。
GDI+ for VCL提供了画笔类TGpPen,TGpPen提供了2个构造方法,一个以TARGB颜色(BCB中为TGpColor类)建立画笔,另一个则以GDI+ 画刷类(TGpBrush)对象建立画笔,实际上,GDI+画笔都是建立在GDI+画刷对象基础上的,以颜色建立画笔, 其实就是以实色刷类TGpSoLidBrush对象建立画笔,所以下面建立的2种画笔是完全等价的,不过第一种方法更简单、方便些而已:
pen:=TGpPen.Create(kcRed);//以颜色建立画笔
brush:=TGpSoildBrush.Create(kcRed);
pen:=TGpPen.Create(brush);//以实色画刷建立画笔
通过TGpPen.PenType可以得到画笔的类型TPenType,实际也就是建立画笔的画刷类型,其定义如下:
TPenType = (ptSolidColor, ptHatchFill, ptTextureFill, ptPathGradient, ptLinearGradient);
进一步,通过TGpPen.Brush属性,可以得到画笔内部的画刷(GDI+ for VCL的各种画刷我已经在前面几篇文章中作了介绍)。
下面将TGpPen同VCL的画笔类TPen进行比较,相较TGpPen而言,TPen对象更简单,只相当于以实色画刷对象建立的TGpPen对象。二者(指TPen对象和TGpPen的实色笔对象)都可以设置画笔颜色、宽度和线条式样(TPen多一个psClear,可以做清除;而TGpPen多一个dsCustom,可以自定义线条式样);不同的有:TPen有个Mode属性,可以用来设置笔的作图方式,而TGpPen没有类似属性和方法,所以某些地方不太方便,如鼠标拖曳时的橡皮筋线条,TGpPen对象就没法直接画出这种效果,好在在VCL中使用GDI+的同时,也可使用TPen对象,弥补了这个缺陷;TGpPen可以设置线的对齐方式和复合钢笔(可同时绘制多条平行线)和线帽,还可进行画笔的几何变换,而TPen无这些功能,加之前面所说的TGpPen可以各种GDI+画刷建立对象,所以GDI+的TGpPen比VCL的TPen的功能丰富多了。
首先,看看TGpPen的对齐方式设置。我们知道,无论是TGpPen还是TPen对象,都可设置笔的宽度,默认情况下,线条以基线(宽度为1的线条)为中心,两边均分,而TGpPen还可以改变对齐方式为全部线条宽度都置于基线内侧,下面的代码演示这种2种结果:
var
g:TGpGraphics;
pen:TGpPen;
begin
g:=TGpGraphics.Create(Canvas.Handle);
g.FillRectangle(Brushs[ARGBFromTColor(Color)],GpRect(ClientRect));
pen:=TGpPen.Create($FF00FF00);
pen.Width:=10;
//pen.Alignment:=paInset;
g.DrawRectangle(Pen,10,10,100,100);//画线宽为5的矩形
pen.Color:=KcRed;
Pen.Width:=1;
g.DrawRectangle(Pen,10,10,100,100);//画线宽为1的基线矩形
pen.Free;
g.Free;
end;
图一为默认对齐方式,即pen.Alignment := paCenter,红线为基线,线条以基线为中心均分;图二则是pen.Alignment := paInset对齐方式,线条居于基线之内侧。



这里附带说一下,GDI+画图形,无论是直线、矩形还是椭圆,和TCanvas的画图形有些不一样,实际画的图形长度总是比给出的长度多1线,而且线条位置还受TGpGraphics的线条像素的偏移模式有关,偏移模式定义如下:
TPixelOffsetMode=(
pmDefault,//默认
pmHighSpeed,//高速度、低质量
pmHighQuality,//高质量、低速度
pmNone,//没有任何像素偏移
pmHalf//像素在水平和垂直距离上均偏移-.5个单位,以进行高速锯齿消除
);
比如上面矩形如果设置g.PixelOffsetMode := pmHalf;//或者pmHighQuality时,在屏幕上,整个图形位置会向左上方移动一线(-0.5个像素四舍五入)。
再看看复合线条的设置,下面是.net类库关于复合线条的说明:
复合直线由平行直线和具有不同宽度的空白区域交替组成。数组中的值指定复合直线中每个组件的起始点位置,该位置与钢笔的宽度有关。数组中的第一个值指定第一个组件(直线)的起始位置,相当于钢笔宽的一小部分。数组中的第二个值指定下一个组件(空白)的起始位置,相当于钢笔宽的一小部分。数组中的最后一个值指定最后一个组件的结束位置。
假设要用钢笔绘制两条平行直线,第一条直线的宽度是钢笔宽度的 20 %,将两条直线隔开的空白区域的宽度是钢笔宽度的 50 %,第二条直线的宽度是钢笔宽度的 30 %。先创建 Pen 和实数数组。通过将包含 0.0、0.2、0.7 和 1.0 值的数组传递给此属性来设置复合数组。
如果 Pen 的 Alignment 属性设置为 <link keywords="F:System.Drawing.Drawing2D.PenAlignment.Inset">,则不要设置此属性。
下面的代码演示了上面的举例,设置彼得宽度为20,先在左边画一段直线,然后按上面例子设置复合线条数组后,在右边画一段双线的线段,第一条线占线宽的20%,为4,中间间隔50%的线宽等于10,第二条线则占剩下的30%,为6,效果见图三:
var
g:TGpGraphics;
pen:TGpPen;
begin
g:=TGpGraphics.Create(Canvas.Handle);
pen:=TGpPen.Create(kcRed);
Pen.Width:=20;
g.DrawLine(pen,10,150,110,150);
pen.SetCompoundArray([0.0,0.2,0.7,1.0]);
g.TranslateTransform(110,0);
g.DrawLine(pen,10,150,110,150);
pen.Free;
g.Free;
end;
TGpPen的线条式样是由DashStyle属性决定的,前面已经说了,DashStyle与VCL TPen.Style除最后一个不同外,其它定义相同,不过,TGpPen可以设置线条式样两端的形状,GDI+定义了3种形状,即方形、圆角形和三角尖形,下面的例子设置为圆帽,画出各种线条式样的直线:
var
g:TGpGraphics;
pen:TGpPen;
I:TDashStyle;
begin
g:=TGpGraphics.Create(Canvas.Handle);
g.FillRectangle(Brushs[ARGBFromTColor(Color)],GpRect(ClientRect));
pen:=TGpPen.Create(kcGreen);
pen.Width:=6.0;
pen.DashCap:=dcRound;
g.SmoothingMode:=smAntiAlias;
forI:=Low(TDashStyle)toHigh(TDashStyle)do
begin
ifI=dsCustomthen
pen.SetDashPattern([4,2,1,3]);
pen.DashStyle:=I;
g.TranslateTransform(0,20);
g.DrawLine(Pen,0,0,300,0);
end;
pen.Free;
g.Free;
end;
效果图见图四,最后一条为自定义线条式样,自定义线条数组设置为(4,2,1,3),各个值乘以笔的宽度(例子中为6),分别为第一个线段长24,间隔12,第二线段长6,间隔18,整个直线为这种格式的线段循环。

TGpPen还可以设置线条联接式样,也就是由两条端点相交或重叠的线条联接点的联接式样,定义如下:
TLineJoin=(
ljMiter=0,//斜联接。这将产生一个锐角或切除角
ljBevel=1,//成斜角的联接。这将产生一个斜角。
ljRound=2,//圆形联接。这将在两条线之间产生平滑的圆弧。
ljMiterClipped=3//斜联接。这将产生一个锐角或斜角,
);
下面的代码展示了这几种联结式样:
procedurePaintLine(g:TGpGraphics);
var
path:TGpGraphicsPath;
pen:TGpPen;
I:TLineJoin;
begin
path:=TGpGraphicsPath.Create;
path.AddRectangle(10,10,100,100);
pen:=TGpPen.Create(kcBlue,6);
forI:=Low(TLineJoin)toHigh(TLineJoin)do
begin
pen.LineJoin:=I;
g.DrawPath(pen,path);
g.TranslateTransform(110,0);
end;
pen.Free;
path.Free;
end;
效果图如下,说明一下,因疏忽,Delphi的Gdiplus.pas第843行,原LineJoinRound应改为ljRound:

TGpPen最具特色的就是可以定义线条两端的形状(线帽TLineCap),注意,这里的线帽形状和上面线条式样的形状TDashCap是两个不同的概念,前者是所要绘制的整个线条两端的形状;后者则是指线条式样两端的形状,一个线条是由无数个线条式样组成的。下面的C++代码绘制了2条不同线帽的直线,见图五:
void__fastcallTForm1::PaintLines(TGpGraphics*g)
{
TGpPen*pen=newTGpPen(kcBlue,10);
g->SmoothingMode=smAntiAlias;
//绘制开始方形线帽,结束菱形线帽的实线直线
pen->StartCap=lcSquareAnchor;
pen->EndCap=lcDiamondAnchor;
g->DrawLine(pen,20,20,300,20);
//绘制开始圆头线帽,结束箭头线帽的虚线直线
pen->DashStyle=dsDash;
pen->StartCap=lcRoundAnchor;
pen->EndCap=lcArrowAnchor;
g->TranslateTransform(0,40);
g->DrawLine(pen,20,20,300,20);
deletepen;
}

GDI+还可以自定义画笔的线帽,下面移植MSDN上的一个自定义线帽例子作为本文的结束:
procedureTForm1.FormPaint(Sender:TObject);
const
points:array[0..2]ofTGpPoint=
((X:100;Y:100),(X:200;Y:50),(X:250;Y:300));
var
g:TGpGraphics;
capPen,customCapPen:TGpPen;
HookCap:TGpCustomLineCap;
path:TGpGraphicsPath;
StartCap,Endcap:TLineCap;
begin
g:=TGpGraphics.Create(Canvas.Handle);
//用窗体颜色填充窗体背景
g.FillRectangle(Brushs[ARGBFromTColor(Color)],GpRect(ClientRect));
//建立一个路径
path:=TGpGraphicsPath.Create;
path.AddLine(GpPoint(0,0),GpPoint(0,5));
path.AddLine(GpPoint(0,5),GpPoint(5,1));
path.AddLine(GpPoint(5,1),GpPoint(3,1));
//建立自定义线帽
HookCap:=TGpCustomLineCap.Create(nil,path);
//设置用于构成自定义线帽的起始线帽和结束线帽
HookCap.SetStrokeCaps(lcRound,lcRound);
//建立宽度为5的黑色画笔
customCapPen:=TGpPen.Create(kcBlack,5);
//设置黑色画笔自的起始线帽和结束线帽为自定义线帽
customCapPen.SetCustomStartCap(HookCap);
customCapPen.SetCustomEndCap(HookCap);
//建立宽度为10的红色画笔
capPen:=TGpPen.Create(kcRed,10);
//获取用于构成自定义线帽的起始线帽和结束线帽
HookCap.GetStrokeCaps(StartCap,EndCap);
//设置红色画笔的起始线帽和结束线帽(本例实际为圆头帽:lcRound)
capPen.StartCap:=StartCap;
capPen.EndCap:=EndCap;
//绘制图案
g.SmoothingMode:=smAntiAlias;
g.DrawLines(capPen,points);
g.DrawLines(customCapPen,points);
HookCap.Free;
path.Free;
capPen.Free;
customCapPen.Free;
g.Free;
end;
效果图如下:

分享到:
相关推荐
GDI+ for VCL基础是关于在Delphi和C++Builder中使用GDI+图形库进行图形绘制和图像处理的专题。GDI+是微软在Windows XP系统中引入的一个增强图形设备接口,它扩展了传统的GDI(Graphics Device Interface),提供了更...
GDI+ for VCL 是一个专门为 Delphi 和 C++Builder 开发者设计的库,它允许程序员利用 GDI+(图形设备接口加)的功能在这些编程环境中创建丰富的图形和图像处理应用。GDI+ 是微软提供的一种图形绘制技术,比传统的 ...
GDI+ for VCL 基础 -- 画笔 GDI+ 提供了许多绘图方法,如直线、曲线、圆弧、矩形、椭圆、扇形、多边形以及路径线条等,这些图形都需要使用 GDI+ 画笔对象。 GDI+ for VCL 基础 -- 画刷 GDI+ for VCL 提供了许多种...
GDI+提供了丰富的图形对象,如画刷、画笔、图像、字体等,以及用于绘制这些对象的方法。在Delphi中,我们可以导入GDI+的头文件(如GDIPAPI.dcu和GDIPOBJ.dcu),以便在我们的项目中使用GDI+的功能。 创建任意图片...
在本文中,我们将深入探讨如何在C++ Builder 6中使用GDI+技术来创建一个时钟应用程序。GDI+是Microsoft提供的一种图形设备接口,它扩展了传统的GDI(图形设备接口)功能,提供了更丰富的绘图能力,包括矢量图形、抗...
在Delphi中,我们可以利用GDI+(Graphics Device Interface Plus)或VCL(Visual Component Library)中的图形组件来绘制矢量图。GDI+提供了丰富的绘图函数,包括画线、填充区域、绘制曲线、旋转、缩放等,使得...
GDI+ 提供了丰富的图形绘制和图像处理功能,如画刷、画笔、位图等对象,可以用来读取、显示、编辑和保存图像。而 Indy 库则是一个更为全面的网络和通信组件集合,尽管它并不专门用于图像处理,但某些情况下也可以...
这通常需要使用图像处理库,如GDI+或FreeImage,提供橡皮擦、画笔、文字添加等功能。 6. **保存和分享**:截图完成后,用户应能够保存图片至本地或直接分享到社交网络。这需要实现文件保存对话框(TOpenDialog/...
C++Builder是一款强大的集成开发环境,它以其对C++语言的深入支持以及丰富的VCL(Visual Component Library)组件库而闻名。在这个项目中,“C++Builder制作成的放大镜”是一个利用C++Builder开发的软件工具,其核心...
GDI+提供了基本的绘图工具,如画刷、画笔、图形路径等,可以用于实现简单的图像编辑功能。而DirectX则更为底层,能实现更复杂的图形处理和高性能的游戏开发。 【标签】:“图像处理” 标签“图像处理”揭示了程序...
4. **画笔和画刷对象**:GDI+提供了TPen和TPenStyle等类来控制线条的样式、颜色和宽度,以及TPenCap和TPenJoin定义线条端点和连接方式。TPenBrush类则用于设置填充颜色和样式。 5. **图形坐标系统**:在绘图程序中...
5. **使用 GDI+**:虽然 Delphi 自带的 GDI 图形库可以实现基础效果,但若想获得更精细的阴影和立体效果,可以考虑使用 GDI+。GDI+ 提供了更多的图形渲染功能,如羽化(Blur)效果,能更好地模拟真实的阴影和投影。 ...
2. **绘图对象**:GDI提供了一系列的绘图对象,如画笔(Pen)、刷子(Brush)、字体(Font)等。开发者可以创建这些对象并设置其属性,然后通过DC进行绘制。 3. **几何形状**:GDI可以绘制各种几何形状,如线条、...
在这个例子中,我们首先获取窗体的客户区矩形,然后使用FillRect填充红色,Pen和Brush分别代表了GDI中的画笔和画刷。通过设置它们的颜色和宽度,我们可以改变绘制的外观。 GDI还可以用于更复杂的绘图操作,如自定义...
在实现水波纹效果时,开发者可能使用GDI+的画刷、画笔和路径对象来绘制和操纵图形。 2. **位图操作**:水波纹效果通常需要对位图进行实时更新,这涉及到位图的加载、创建、复制以及像素操作。开发者需要理解如何...
文档中还提到了如何设置画笔颜色、填充矩形等,这些都是GDI提供的绘图功能。在Windows平台上,GDI和其后继者GDI+为界面元素的绘制提供了底层支持。 5. VCL框架 文档内容提到使用CB6.0创建应用程序,CB即CodeGear ...
Delphi技巧仓库是一个集合了众多Delphi编程技巧的资源库,涵盖了从基础到高级的各种技巧,旨在帮助开发者提升效率,优化代码,解决实际问题。在Delphi编程中,掌握这些技巧能够使你的软件开发工作更加得心应手。下面...
4. **绘图函数**:学习 GDI+ 或 VCL 的绘图函数,如 DrawLine、DrawRect、FillRegion 等,用于在画板上绘制图形。 5. **图像处理**:可能涉及基本的图像加载、保存、缩放、旋转等操作,需要理解如何使用 TImage 或...
7. **图像编辑**:高级的屏幕截取系统可能包含简单的图像编辑功能,如剪切、复制、粘贴、画笔等。这需要对图像处理算法有所了解,并可能涉及额外的图形库,如Free Pascal的GR32或第三方库如GDI+。 8. **自定义组件*...
GDI+提供了丰富的绘图对象,如Pen(画笔)、Brush(刷子)和Graphics(图形上下文),这些对象可以用来绘制和填充图形。 源代码中可能包括以下几个关键部分: 1. 主窗体(Form)的创建:在Delphi中,一个窗体是应用...