谁有类似于画笔那样的画图源程序,Delphi有没有自带的示例,我找不着。

解决方案 »

  1.   

    查看帮助,对TCanvas了解后自然就懂了
      

  2.   

    1. TCanvas,TPen,TBrush,TColor对象的方法及属性;
    2. 绘图功能的实现;
    3. TImage,TPicture,TBitBtn,TBitmap部件的方法及属性;
    4. 图像观测及处理。Graphex.dpr是一个简单的图形图像应用程序,是对以上这些对象和组
    件的具体应用。 TCanvas对象是一个用于绘图的表面,在这个区域上,程序可实现各种
    绘图功能,很多部件(如TIMage,TMemo)的Canvas属性就是TCanvas对象。在
    部件上绘制图形就是在部件的画布上绘制。TCanvas的Brush,Pen,Font属性
    分别是TBrush,TPen,TFont对象,它们用于定义绘制图形的风格。关于
    TBrush,TPen对象,下节中将详细介绍。画布的笔的位置定义在PenPos属性中,可用MoveTo方法来移动笔。如
    果要在画布上输出文本,可用Textout方法。TCanvas有对象很多方法,可完成常用的绘图功能,现将方法及功能简
    介: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);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);
    DrawFocuseRect;DrawFocusRect(Const Rect : TRect)此方法绘制一矩形
    以指示此矩形获得焦点。此方法是异或(XOR)函数,第二次调用时原有矩形
    将消失。DrawFocuseRect绘制的矩形不能滚动。要实现滚动功能则先调用
    此方法使矩形消失,待滚动过后重新绘制。Tpen Object(画笔对象)
    应用程序常用TPen对象在画布上绘制各种线段,笔的颜色在Color属性中定
    义。线段宽度在Width属性中定义。
    Style属性定义了线段的各种类型如:
    Styled的取值及含义
    Style     含义PSolod    画固定线段
    PSDash    画由下划线组成的线段
    PSDot    画由点组成的线段
    PsDashDot  画点划线
    PsClear   画双点划线
    PsClear   画看不见的线段
    PsInsideFrame 画边界的矩形线框Mode属性定义线段的颜色。可结合当前的颜色、屏幕颜色或它们反转
    值,对线段的颜色重新定义,但不改变Color属性。
    Mode的取值及含义Mode   象素颜色PmBlack      黑色
    PmWhite      白色
    PmNop        不变
    PmCopy       使用Color属性中的颜色
    PmNotCopy     笔颜色的反转值
    PmMergePenNot   笔的颜色与屏幕颜色反转值的结合
    PmNaskNotPen    屏幕颜色与笔颜色
    PmMergeNotPen   屏幕颜色与笔颜色反转值的结合TBrush OBject(画刷对象)
    画刷对象用以填充图形,如用画刷颜色或图案对矩形或椭圆进行填
    充。TBrush拥有一个画刷句柄(HBrush)。
    画刷的颜色定义在Color属性中。画刷还有一个Bitmap属性,该属性只
    能在运行时得到,画刷可使用位图填充图形以产生特殊效果。位图大小为8
    个象素点,高8个象素点宽。
    Style属性定义了画刷填充图形的风格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。图形程序的开发Graphex.dpr是一个简单的图形图像应用程序。该程序可用鼠标绘制多种图形,可设置画笔颜色、画刷填充方式;另外还可以浏览位图、元文件、图标,改变它们的大小,并打印。
     在工具条中添加加速按钮
     响应鼠标事件
     设置画笔和画刷
     实现绘图的“橡皮擦”功能
     加入状态条在工具条中添加加速按钮加速按钮是应用程序常用的部件,它是替代菜单的快捷形式,通常把
    多个加速按钮集中在一个工具条中以方便使用。Graphex中有三个工具条,
    它们是TPancel部件,面板上有几组加速按钮,用以设置绘图方式、画笔、
    画刷。每个加速按钮的glyph属性是图像对象,位图对象用来指示该按钮是否
    被使用。glyph 通常需要四幅图像,分别表示按下、不按、选择、失效四
    种状态。程序员可根据个人喜好来选择图像。
    加速按钮使用图像来告诉用户其状态和目的,因为按钮上无标题, 因
    此应给用户正确的提示: 把Down属性设置成真值使加速按钮呈按下状态
     把Enable属性设置成假值使加速按钮呈失效状态。
    例程中缺省的绘图工具是画线,因此应用程序开始时画线按钮呈按下
    状态。
    在应用程序中,常把一些功能相似的按钮放在一起,用户在同一时刻
    只能选择其中的一个按钮。当其它按钮按下时,原来被按下的按钮自动弹
    起,这些选择排它的按钮称为一组加速按钮。
    要使多个加速按钮成为一组,将这些按钮的GraphIndex属性设成相同
    的值。最简单的办法是在设计状态时,用鼠标选中各个加速按钮,然后设
    置GraphIndex值。
    有时用户按一个已经按下的按钮,希望该按钮能够弹起,这样没有任
    何按钮被按下,使用AllowAllup 属性可实现上述功能。对于一组加速按钮
    来讲,设置该组中任一按钮的AllowAllup可使这组的每一个按钮具有这种
    功能。
    Graphex程序中设计了三组加速按钮和两个单独的加速按钮。 第一组加速
    按钮用来选择绘图工具,它与两个单独的按钮处在同一面板中,这个面板
    是缺省可见的。另外两个按钮分别代表画笔、画刷。第二组与第三组加速
    按钮处在两个缺省不可见的面板中,它们分别代表不同风格的画笔和画
    刷,只有按下第一个面板中的画笔(或画刷)按钮,第二(或第三) 个面板才
    会显示,这样用户就可以选择画笔、画刷了。响应鼠标事件鼠标常被用作绘图的工具,应用程序利用鼠标位置的变化来绘制各种
    不同的图形。鼠标有三个动作:鼠标按钮按下、鼠标移动、鼠标按钮弹
    起。在Delphi中, 对应三个动作有三个不同的事件:
    OnMouseDown,OnMouseMove,OnMouseUp。当Dlephi应用程序探测到一个鼠标动作时,它传递五个参数,并调用相应
    的事件响应。程序员可利用这些参数来定义事件程序。
    鼠标事件的五个参数 参数      含义Sender   探测鼠标动作的对象
    Button   涉及的鼠标按钮:左键,中键,右键
    Shift   鼠标动作时,Alt,Ctrl,Shift按钮的状态
    X,Y 事件发生时鼠标的坐标
    当鼠标按下时发生OnMouseDown事件。举一个简单例子来说明程序如何
    对该事件进行响应。假如我们想在鼠标按下的地方出现"Here"。
    可在该事件中调用TextOut方法:
    procedure TForm1.FormMouseDown(Sender: TObject,Button:
    TMouseButton;Shift : TShifState; X,Y : Integer);
    begin
    Canvas.TextOut(X, Y, 'Here!');
    end;
    用户放松鼠标键时发
      

  3.   

    绘图功能的实现绘图软件常根据用户的要求改变绘图工具。Graphex.dpr例程中,当用
    户按下某个按钮时,可选择绘图工具中的画笔或画刷,在程序类型说明部
    分定义了五种绘图工具。
    type
    TDrawingTool =(dtLine,dtRectangle,dtEllips,dtRoundRect,dtPolygon);当选中某种按钮,则选中了相应的绘图工具,如:
    procedure TForm1.LineButtonClick(Sender: TObject);
    begin
    DrawingTool := dtLine;
    end;
    procedure TForm1.RectangleButtonClick(Sender: TObject);
    begin
    DrawingTool := dtRectangle;
    end;
    procedure TForm1.EllipseButtonClick(Sender: TObject);
    begin
    DrawingTool := dtEllipse;
    end;
    procedure TForm1.RoundRectButtonClick(Sender: TObject);
    begin
    DrawingTool := dtRoundRect;
    end;
    procedure TForm1.PolygonButtonClick(Sender: TObject);
    begin
    DrawingTool :=dtPolygon;
    end; DrawShape过程定义了每种绘图工具的动作:
    procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode:
    TPenMode);
    begin
    with Image.Canvas do
    begin
    Pen.Mode := AMode;
    case DrawingTool of
    dtLine: begin
    MoveTo(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;程序刚运行时,只有一个工具栏。当用户单击画笔和画刷时,则出现相
    应的工具栏。其代码如下:
    procedure TForm1.PenButtonClick(Sender: TObject);
    begin
    PenBar.Visible := PenButton.Down;
    end;
    procedure TForm1.BrushButtonClick(Sender: TObject);
    begin
    BrushBar.Visible := BrushButton.Down;
    end;在设计绘图程序时,还要解决一些问题。如为了在鼠标移动时能观测
    图形的变化,我们定义了OnMouseMove事件。但会出现这样的现象,当鼠标
    进入绘图区时,用户未按下鼠标键,画布上却出现绘制的图形,这是我们
    不希望看到的。其原因是没有对鼠标按钮是否按下进行判断。因此在窗体
    对象中定义了drawing的域,当鼠标按钮按下时,drawing 设置成真值。只
    有drawing为真,鼠标移动才执行绘图功能;当鼠标键松开时,drawing设
    置成假,鼠标移动将不执行绘图动作。另外一个问题是, 我们希望得到的是鼠标按钮按下和松开这两点所形
    成的图形,但OnMouseMove却把鼠标轨迹上各点与起始点所形成的所有图形
    画在屏幕上,这同样是我们不希望看到的,为了解决这些问题,程序定义
    了鼠标的三个事件:procedure TForm1.FormMouseDown(Sender: TObject; Button:TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    Drawing := 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);
    begin
    if Drawing then
    DrawShape(Origin, Point(X, Y), pmCopy);
    Drawing := False;
    end;
    procedure TForm1.FormMouseMove(Sender: TObject; Shift:TShiftState; X,Y: Integer);
    begin
    if Drawing then
    begin
    DrawShape(Origin, MovePt, pmNotXor);
    MovePt := Point(X, Y);
    DrawShape(Origin, MovePt, pmNotXor);
    end; MovePt用来记录鼠标当前位置。当下次鼠标移动时, 就能在上次鼠标
    绘制的图形上画一个形状、大小一样的图形,并把画笔颜色设置成
    PmNotXor,使上次绘制的图形颜色变成了屏幕颜色,从而达到“橡皮擦”
    的效果。将画笔、画刷的Style属性设置成用户希望的值,可实现对画笔和画刷
    风格的选择。procedure TForm1.SetBrushStyle(Sender: TObject);
    begin
    with Image.Canvas.Brush do
    begin
    if Sender = SolidBrush then Style := bsSolid
    else if Sender = ClearBrush then Style := bsClear
    else if Sender = HorizontalBrush then Style := bsHorizontal
    else if Sender = VerticalBrush then Style := bsVertical
    else if Sender = FDiagonalBrush then Style := bsFDiagonal
    else if Sender = BDiagonalBrush then Style := bsBDiagonal
    else if Sender = CrossBrush then Style := bsCross
    else if Sender = DiagCrossBrush then Style := bsDiagCross;
    end;procedure TForm1.SetPenStyle(Sender: TObject);
    begin
    with Image.Canvas.Pen do
    begin
    if Sender = SolidPen then Style := psSolid
    else if Sender = DashPen then Style := psDash
    else if Sender = DotPen then Style := psDot
    else if Sender = DashDotPen then Style := psDashDot
    else if Sender = DashDotDotPen then Style := psDashDotDot
    else if Sender = ClearPen then Style := psClear;
    end;
    end;图像对象概述TGraphic对象
    TGraphic对象是TBitmap ,TIcon,Tmetafile对象的基类。如果知道图
    像的具体类型( 如位图, 图标元文件) , 则应将图像贮存在相应类型的
    对象中( 如TBitmap,TIcon,Tmetafile),否则应该使用可贮存任何图像类
    型的TPicture对象。TPicture对象
    TPicture对象可以保存位图、图标或元文件。Graphic属性中包括图像
    的类型;图像的高度和宽度分别定义在Height,Width属性中;调用
    LoadFromFile方法,可以从文件中装载一幅图像:
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    BitBtn1.Glyph.LoadFromFile('TARTAN.BMP');
    end;
    要保存一个位图,则要用SaveToFile方法;要把图像复制到剪切板,可以
    调用TClipboard对象的Assign方法。TImage部件
    TImage部件用以在窗体中显示图像,它的Picture 属性保存着要显示
    的图像, 这是一个TPicture对象。AutoSize,Stretch属性是用来调节部件
    与图像的大小的。当AutoSize 为真值时,TImage部件将根据它所包含的图
    像的大小来调整自身的大小;当AutoSize为假值时,不论图像有多大,部
    件将保持设计时的大小。如果部件比图像小, 那么只有一部分图像是可见
    的。当Stretch为真值时,位图像将根据部件的大小调整自身的大小,当部
    件大小改变时,元文件也做相应变化。Stretch属性对图标没有作用。TBitmap Object(位图对象)位图对象包含一个位图图像,有HBITMAP,HPALETE句柄,可自动管理调
    色板。位图对象也有画布属性。位图的Palette属性用来控制位图的颜色映
    射,它包括256种可显示的颜色。 如果应用程序用前景色绘制位图,
    Palette 属性的颜色将被加入Windows系统调色板,其它颜色被映射到系统
    调色板已存在的颜色。如果应用程序用自己的颜色绘制位图,而其它程序
    已占有系统调色板,位图的颜色将被映射到系统调色板中。如果Monochrome属性设置成假,位图将显示成彩色,反之显示成黑白
    色。调用Draw和StretchDraw方法可在画布上绘制位图。图像对象的应用本章例程中,单击(文件|浏览)菜单项,将弹出一个图像浏览窗体。
    如果用户在窗体中选择文件列表框的图形文件,窗体右上角的图像部件上
    将出现此文件所代表的图像;若选择“雕刻效果”按钮中检查框,窗体中
    的加速按钮和位图按钮上将出现位图。以下代码是将图像文件装载至图像部件上:procedure TImageForm.FileListBox1Click(Sender: TObject);
    var
    FileExt: string[4];
    begin
    FileExt := UpperCase(ExtractFileExt(FileListBox1.Filename));
    if (FileExt = '.BMP') or (FileExt = '.ICO') or (FileExt = '.WMF')
    then
    begin
    Image1.Picture.LoadFromFile(FileListBox1.Filename);
    Label1.Caption := ExtractFilename(FileListBox1.Filename);
    if (FileExt = '.BMP') then
    begin
    Label1.Caption := Label1.Caption + 
    Format(' (%d x %d)', [Image1.Picture.Height,Image1.Picture.Width]);
    ViewForm.Image1.Picture.Bitmap := Image1.Picture.Bitmap;
    ViewAsGlyph(FileExt);
    end;
    if FileExt = '.ICO' then Icon := Image1.Picture.Icon;
    if FileExt = '.WMF' then 
    ViewForm.Image1.Picture.Metafile := Image1.Picture.Metafile;
    end;
    end;  这个过程首先判断文件类型,如果是图像文件,则将图像装载至图像部件
    上,并在标签上列出文件名称。如果是位图文件,还将显示其大小。在加速按钮和位图按钮中显示位图的代码如下:procedure TImageForm.CheckBox1Click(Sender: TObject); 
    begin
    ViewAsGlyph(UpperCase(ExtractFileExt(FileListBox1.Filename)));
    end;procedure TImageForm.ViewAsGlyph(const FileExt: string);
    begin
    if CheckBox1.Checked and (FileExt = '.BMP') then 
    begin
    SpeedButton1.Glyph := Image1.Picture.Bitmap;
    SpeedButton2.Glyph := Image1.Picture.Bitmap;
    SpinEdit1.Value := SpeedButton1.NumGlyphs;
    BitBtn1.Glyph := Image1.Picture.Bitmap;
    BitBtn2.Glyph := Image1.Picture.Bitmap;
    end;
    end;窗体中有一个检查框用来检验图像部件的Strecth 属性的效果。当此检查
    框被选中时,Stretch设成真值,图像将根据部件大小调整自身大小。代码
    如下:procedure TImageForm.StretchCheckClick(Sender: TObject);
    begin
    Image1.Stretch := StretchCheck.Checked;
    end; 
    当用户按下标有“全尺寸”字样的按钮时,另一个窗体将显示。如图5.5。
     图像观测窗体在这个窗体中,用户可以在屏幕和打