Delphi图形图像编程

778612645

778612645

2016-02-19 17:48

下面图老师小编跟大家分享一个简单易学的Delphi图形图像编程教程,get新技能是需要行动的,喜欢的朋友赶紧收藏起来学习下吧!

  在Delphi中,专门定义了一组对象和部件用以绘制图形,完成一些简单的图像功能。利用这些对象、部件的方法,可以方便地绘制各种常用图形;通过设置它们的属性,能得到不同风格的图形。另外,通过对鼠标事件的定义,可以方便的设计图形绘制程序。

  本章将介绍以下内容:

  1. TCanvas,TPen,TBrush,TColor对象的方法及属性;

  2. 绘图功能的实现;

  3. TImage,TPicture,TBitBtn,TBitmap部件的方法及属性;

  4. 图像观测及处理。

  Graphex.dpr是一个简单的图形图像应用程序,是对以上这些对象和组件的具体应用。本章将结合此程序进行讲述。  

  5.1 图形对象概述 

  5.1.1 TCanvas Object(画布对象)

  TCanvas对象是一个用于绘图的表面,在这个区域上,程序可实现各种绘图功能,很多部件(如TIMage,TMemo)的Canvas属性就是TCanvas对象。在部件上绘制图形就是在部件的画布上绘制。TCanvas的Brush,Pen,Font属性分别是TBrush,TPen,TFont对象,它们用于定义绘制图形的风格。关于TBrush,TPen对象,下节中将详细介绍。

  画布的笔的位置定义在PenPos属性中,可用MoveTo方法来移动笔。如果要在画布上输出文本,可用Textout方法。

  TCanvas有对象很多方法,可完成常用的绘图功能,现将方法及功能简介如表5.1: 

  表5.1 TCanvas对象的方法

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  方法名称         形式及说明

  ───────────────────────────────────────

  Arc Arc(x1,y1,x2,y2,x3,y3,x4,y4 : Integer);

  Arc方法在椭圆上画一段弧,椭圆由(x1,y1),(x2,y2) 两点所确定的椭圆所决

  定。弧的起点是椭圆圆周和椭圆中心与(x3,y3)连线的交点。弧矩形终点是椭

  圆圆周和椭圆中心与(x4,y4)连线的交点,以逆时针方向画弧。

  Chord Chord(x1,y1,x2,yx,x3,y3,x4,y4 : Integer);

  Chord方法连接椭圆上的两点,椭圆由(x1,y1),(x2,y3) 两点所确定的矩形决

  定,(x3,y3)是始点,(x4,y4)是终点。

  Brushcopy Brushcopy(const Dest : TRect;Bitmap : TBitmap;const Source TRect;

  Color : TColor);

  Brushcopy方法把位图的一部分复制到画布的某个矩形区域,并用画笔的当前颜色替换位图的颜色。参数Dest定义画布的一个矩形区域,该矩形用以填充位图,Bitmap定义位图;Source定义位图中的矩形区域,该区域上的位图

  将被复制;Color定义画笔中,用以替换位图的颜色。

  CopyRect CopyRect(Dest : TRect;Canvas : TCanvas; Source TRect);

  此方法从另一个画布对象上复制部分图像到该画布。Canvas表示源画布,Source是源画布上要复制的图像区域。Dest表示目标画布上将接受复制

  图像的矩形区域。

  Draw Draw(x,y : Integer;Graphic : TGraphic);

  此方法在画布给定的象素点坐标(x,y)处画Graphic所给的图像,该图像可以是位图,图标或元位图。

  Ellips Ellips(x1,y1,x2,y2 : Integer);

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

  Ellips方法在画布指定的矩形边界上画一个椭圆,(x1,y1)是矩形左上角的象素坐标,x2,y2是矩形右下角的象素坐标。如果矩形形成一个区域,将出现一个椭圆。

  LineTo LineTo(x,y : Integer);

  LineTo从当前位置画一条线至(x,y)所指定的位置,并把笔的位置移至(x ,y)。

  MoveTo MoveTo(x,y : Integer);

  MoveTo 将笔的当前位置设置到点(x,y)处,笔的当前位置在PenPos属性中,

  改变笔的当前位置使用MoveTo方法,不要设法改变PenPos的值。

  Die Die(x1,y1,x2,y2,x3,y3,x4,y4 : Longint);

  Die方法绘制椭圆的一部分,椭圆由点(x1,y1),(x2,y2)所指定的矩形所决定,制的那部分由椭圆中心到(x3,y3),(x4,y4)两点的两条辐射线所决定。

  Polygon Polygon(Points : array of TPrint);

  Polygon方法在画布上绘制一系列的点,各点依次连成线,最后将首尾两点相接形成一个区域,并用当前笔刷填充此区域。

  Polyline Polyline(Ports : array of TPort);

  Polyline方法在画布上用当前画笔绘制一系列的点,各点依次连成线。

  StretchDraw StretchDraw(Const Rect : TRcct : Graphic : TGraphic);

  此方法在Rect参数指定的矩形内画一图像。图像延伸改变大小以适应矩形。

  

Rectangle Rectangle(X1,y1,x2,y2 : Integer);Rectangle方法在画布上用当前画刷绘制矩形,(x1,y1)是矩形的左上角,(x2,y2)是矩形的右下角。RomlRect RomlRect((x1,y1,x2,y2,x3,y3, : Integer);DrawFocuseRectDrawFocusRect(Const Rect : TRect)

  此方法绘制一矩形以指示此矩形获得焦点。此方法是异或(XOR)函数,第二次调用时原有矩形将消失。DrawFocuseRect绘制的矩形不能滚动。要实现滚动功能则先调用此方法使矩形消失,待滚动过后重新绘制。

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

  5.1.2 Tpen Object(画笔对象) 

  应用程序常用TPen对象在画布上绘制各种线段,笔的颜色在Color属性中定义。线段宽度在Width属性中定义。

  Style属性定义了线段的各种类型,如表5.2: 

  表5.2 Styled的取值及含义

  ━━━━━━━━━━━━━━━━━━━━━━

  Style     含义

  ──────────────────────

  PSolod 画固定线段

  PSDash 画由下划线组成的线段

  PSDot 画由点组成的线段

  PsDashDot 画点划线

  PsClear 画双点划线

  PsClear 画看不见的线段

  PsInsideFrame 画边界的矩形线框

  ━━━━━━━━━━━━━━━━━━━━━━━

  Mode属性定义线段的颜色。可结合当前的颜色、屏幕颜色或它们反转值,对线段的颜色重新定义,但不改变Color属性。详见表5.3。 

  表5.3 Mode的取值及含义

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━

  Mode 象素颜色

  ──────────────────────────

  PmBlack 黑色

  PmWhite 白色

  PmNop 不变

  PmCopy 使用Color属性中的颜色

  PmNotCopy 笔颜色的反转值

  PmMergePenNot 笔的颜色与屏幕颜色反转值的结合

  PmNaskNotPen 屏幕颜色与笔颜色

  PmMergeNotPen 屏幕颜色与笔颜色反转值的结合

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

  5.1.3 TBrush OBject(画刷对象)

  画刷对象用以填充图形,如用画刷颜色或图案对矩形或椭圆进行填充。TBrush拥有一个画刷句柄(HBrush)。

  画刷的颜色定义在Color属性中。画刷还有一个Bitmap属性,该属性只能在运行时得到,画刷可使用位图填充图形以产生特殊效果。位图大小为8个象素点,高8个象素点宽。

  Style属性定义了画刷填充图形的风格。

  5.1.4 TColor类型

  TColor类型用于定义一个对象的颜色。很多部件的颜色属性就是TColor 类型, 在Graphics单元中TColor定义如下:

  TColor = -(COLOR_ENDCOLORS + 1)..$02FFFFF;

  这是一个32位二进制数据。Graphic单元中还定义了一些常用的颜色常量,这些常量或直接映射成系统调色板中最相近的颜色,或映射成Wondows 控制面板中颜色部分的系统视频颜色。

  直接映射成系统调色板中的颜色有: 

  ClAqua,CLBlack,ClBlue,ClbkGrray,ClFuchsoa......ClYellow

  映射程序用4字节的二进制码来定义颜色,低3 位字节代表RGB 相应的颜色,如$00FF0000表示纯蓝,$0000FF00表示纯绿,$000000FF表示纯红,$00000000表示黑色,$00FFFFFF表示白色。如果最高位字节是$00,则表示用系统调色板中最相近的颜色;最高位字节是$01,则表示用当前调色板中最相近的颜色匹配;最高位字节是$02,则用当前设备描述表中逻辑调色板的次相近颜色匹配。

  用Windows API的SelectPalette函数可创建逻辑调色板,要实现逻辑调色板到硬件调色板的映射,需用函数RealizePalett 

  5.2 图形程序的开发 

  Graphex.dpr是一个简单的图形图像应用程序,运行状态如图5.2。该程序可用鼠标绘制多种图形,可设置画笔颜色、画刷填充方式;另外还可以浏览位图、元文件、图标,改变它们的大小,并打印。本节结合例程讲述以下问题:

  ● 在工具条中添加加速按钮

  ● 响应鼠标事件

  ● 设置画笔和画刷

  ● 实现绘图的橡皮擦功能

  ● 加入状态条

  5.2.1 在工具条中添加加速按钮 

  加速按钮是应用程序常用的部件,它是替代菜单的快捷形式,通常把多个加速按钮集中在一个工具条中以方便使用。Graphex中有三个工具条,它们是TPancel部件,面板上有几组加速按钮,用以设置绘图方式、画笔、画刷。

  每个加速按钮的glyph属性是图像对象,位图对象用来指示该按钮是否被使用。glyph 通常需要四幅图像,分别表示按下、不按、选择、失效四种状态。程序员可根据个人喜好来选择图像。

  加速按钮使用图像来告诉用户其状态和目的,因为按钮上无标题, 因此应给用户正确的提示:

  ● 把Down属性设置成真值使加速按钮呈按下状态

  ● 把Enable属性设置成假值使加速按钮呈失效状态。 

  例程中缺省的绘图工具是画线,因此应用程序开始时画线按钮呈按下状态。

  在应用程序中,常把一些功能相似的按钮放在一起,用户在同一时刻只能选择其中的一个按钮。当其它按钮按下时,原来被按下的按钮自动弹起,这些选择排它的按钮称为一组加速按钮。

  要使多个加速按钮成为一组,将这些按钮的GraphIndex属性设成相同的值。最简单的办法是在设计状态时,用鼠标选中各个加速按钮,然后设置GraphIndex值。

  有时用户按一个已经按下的按钮,希望该按钮能够弹起,这样没有任何按钮被按下,使用AllowAllup 属性可实现上述功能。对于一组加速按钮来讲,设置该组中任一按钮的AllowAllup可使这组的每一个按钮具有这种功能。

  Graphex程序中设计了三组加速按钮和两个单独的加速按钮。 第一组加速按钮用来选择绘图工具,它与两个单独的按钮处在同一面板中,这个面板是缺省可见的。另外两个按钮分别代表画笔、画刷。第二组与第三组加速按钮处在两个缺省不可见的面板中,它们分别代表不同风格的画笔和画刷,只有按下第一个面板中的画笔(或画刷)按钮,第二(或第三) 个面板才会显示,这样用户就可以选择画笔、画刷了。 

  5.2.2 响应鼠标事件 

  鼠标常被用作绘图的工具,应用程序利用鼠标位置的变化来绘制各种不同的图形。鼠标有三个动作:鼠标按钮按下、鼠标移动、鼠标按钮弹起。在Delphi中, 对应三个动作有三个不同的事件:OnMouseDown,OnMouseMove,OnMouseUp。

  当Dlephi应用程序探测到一个鼠标动作时,它传递五个参数,并调用相应的事件响应。

  程序员可利用这些参数来定义事件程序。五个参数如下表5.4: 

  表5.4 鼠标事件的五个参数

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━

  参数      含义

  ──────────────────────────

  Sender 探测鼠标动作的对象

  Button 涉及的鼠标按钮:左键,中键,右键

  Shift 鼠标动作时,Alt,Ctrl,Shift按钮的状态

  X,Y 事件发生时鼠标的坐标

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

  当鼠标按下时发生OnMouseDown事件。举一个简单例子来说明程序如何对该事件进行响应。假如我们想在鼠标按下的地方出现"Here"。

  响应鼠标的OnMouseDown事件可在该事件中调用TextOut方法: 

  

procedure TForm1.FormMouseDown(Sender: TObject,Button: TMouseButton;Shift : TShifState; X,Y : Integer);beginCanvas.TextOut(X, Y, 'Here!');end;
 

  用户放松鼠标键时发生OnMouseUp事件。该事件发生时,鼠标到达的对象并不一定是鼠标键按下时鼠标所在的对象。例如,用户可在窗体之外画一条线段,(鼠标在窗体外,线段在窗体内)。下面的代码可用鼠标绘制直线:

  

procedure TForm1.FormMouseDown(Sender:TObject)beginMoveto(x,y); end;procedure TForm1.FormMouse Up(Sender:Tobject)beginLineto(X, Y);end;

  画直线时,用户只有在松开鼠标才能看见直线,对直线的变化不能进行实时观测。这是因为鼠标移动时程序没有进行某种应。Delphi定义了OnMouseMove事件来响应鼠标移动。以下代码可使用户随时观测直线的变化: 

  

procedure TForm1.FormMouseMove(Sender:Tobject)beginDrowto(X,Y);Moveto(origin);end.
 

  origin是起始点。

  5.2.3 绘图功能的实现

  绘图软件常根据用户的要求改变绘图工具。Graphex.dpr例程中,当用户按下某个按钮时,可选择绘图工具中的画笔或画刷,在程序类型说明部分定义了五种绘图工具。

  

typeTDrawingTool = (dtLine,dtRectangle,dtEllips,dtRoundRect,dtPolygon);
 

  当选中某种按钮,则选中了相应的绘图工具,如: 

  

procedure TForm1.LineButtonClick(Sender: TObject);beginDrawingTool := dtLine;end; procedure TForm1.RectangleButtonClick(Sender: TObject);beginDrawingTool := dtRectangle;end; procedure TForm1.EllipseButtonClick(Sender: TObject);beginDrawingTool := dtEllipse;end; procedure TForm1.RoundRectButtonClick(Sender: TObject);beginDrawingTool := dtRoundRect;end; procedure TForm1.PolygonButtonClick(Sender: TObject);beginDrawingTool :=dtPolygon;end;
  

  DrawShape过程定义了每种绘图工具的动作: 

  

procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);beginwith Image.Canvas dobeginPen.Mode := AMode;case DrawingTool ofdtLine: beginMoveTo(TopLeft.X, TopLeft.Y);LineTo(BottomRight.X, BottomRight.Y);end;dtRectangle: Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);dtEllipse: Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);dtRoundRect: RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y,(TopLeft.X - BottomRight.X) div 2, (TopLeft.Y - BottomRight.Y) div 2);dtPolygon:Polygon([Point(0,0),TopLeft,BottomRight]); end;end;end;
 

  程序刚运行时,只有一个工具栏。当用户单击画笔和画刷时,则出现相应的工具栏,如图5.4。其代码如下: 

  

procedure TForm1.PenButtonClick(Sender: TObject);beginPenBar.Visible := PenButton.Down;end; procedure TForm1.BrushButtonClick(Sender: TObject);beginBrushBar.Visible := BrushButton.Down;end;

  在设计绘图程序时,还要解决一些问题。如为了在鼠标移动时能观测图形的变化,我们定义了OnMouseMove事件。但会出现这样的现象,当鼠标进入绘图区时,用户未按下鼠标键,画布上却出现绘制的图形,这是我们不希望看到的。其原因是没有对鼠标按钮是否按下进行判断。因此在窗体对象中定义了drawing的域,当鼠标按钮按下时,drawing 设置成真值。只有drawing为真,鼠标移动才执行绘图功能;当鼠标键松开时,drawing设置成假,鼠标移动将不执行绘图动作。

  另外一个问题是, 我们希望得到的是鼠标按钮按下和松开这两点所形成的图形,但OnMouseMove却把鼠标轨迹上各点与起始点所形成的所有图形画在屏幕上,这同样是我们不希望看到的,为了解决这些问题,程序定义了鼠标的三个事件: 

  

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);beginDrawing := True;Image.Canvas.MoveTo(X, Y);Origin := Point(X, Y);MovePt := Origin;OriginPanel.Caption := Format('Origin: (%d, %d)', [X, Y]);end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);beginif Drawing thenDrawShape(Origin, Point(X, Y), pmCopy);Drawing := False;end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);beginif Drawing thenbeginDrawShape(Origin, MovePt, pmNotXor);MovePt := Point(X, Y);DrawShape(Origin, MovePt, pmNotXor);end;
  

  MovePt用来记录鼠标当前位置。当下次鼠标移动时, 就能在上次鼠标绘制的图形上画一个形状、大小一样的图形,并把画笔颜色设置成PmNotXor,使上次绘制的图形颜色变成了屏幕颜色,从而达到橡皮擦的效果。

  将画笔、画刷的Style属性设置成用户希望的值,可实现对画笔和画刷风格的选择。 

  

procedure TForm1.SetBrushStyle(Sender: TObject);beginwith Image.Canvas.Brush dobeginif Sender = SolidBrush then Style := bsSolidelse if Sender = ClearBrush then Style := bsClearelse if Sender = HorizontalBrush then Style := bsHorizontalelse if Sender = VerticalBrush then Style := bsVerticalelse if Sender = FDiagonalBrush then Style := bsFDiagonalelse if Sender = BDiagonalBrush then Style := bsBDiagonalelse if Sender = CrossBrush then Style := bsCrosselse if Sender = DiagCrossBrush then Style := bsDiagCross;end; procedure TForm1.SetPenStyle(Sender: TObject);beginwith Image.Canvas.Pen dobeginif Sender = SolidPen then Style := psSolidelse if Sender = DashPen then Style := psDashelse if Sender = DotPen then Style := psDotelse if Sender = DashDotPen then Style := psDashDotelse if Sender = DashDotDotPen then Style := psDashDotDotelse if Sender = ClearPen then Style := psClear;end;end;
 

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)
展开更多 50%)
分享

猜你喜欢

Delphi图形图像编程

编程语言 网络编程
Delphi图形图像编程

Delphi图形图像编程(二)

Delphi
Delphi图形图像编程(二)

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Delphi图形图像编程(一)

Delphi
Delphi图形图像编程(一)

Linux图形图像处理软件(三)

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
Linux图形图像处理软件(三)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

常见图形图像文件扩展名一览

PS PS教程
常见图形图像文件扩展名一览

Delphi 拖放编程

编程语言 网络编程
Delphi 拖放编程

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

win10我的电脑显示桌面的方法

win10我的电脑显示桌面的方法

windows 10预览版怎么设置多屏显示?

windows 10预览版怎么设置多屏显示?
下拉加载更多内容 ↓