在图像上绘制多边形

3

我已经搜索了很长时间,但是没有找到答案。

我想在图像上绘制多边形,但是我想通过创建点来完成这个操作;使用 MouseCursor 创建特定的点,并且通过一个按钮沿着这些点画出一条线;

我找到了以下内容:

var
  Poly: array of TPoint;
begin  
   // Allocate dynamic array of TPoint
   SetLength(Poly, 6);

  // Set array elements
  Poly[0] := Point(10, 10);
  Poly[1] := Point(30, 5);
  Poly[2] := Point(100, 20);
  Poly[3] := Point(120, 100);
  Poly[4] := Point(50, 120);
  Poly[5] := Point(10, 60);

  // Pass to drawing routine
  Canvas.Polygon(Poly);

  // Redim if needed
  SetLength(Poly, 7);
  Poly[6] := Point(1, 5);

  // Pass to drawing routine
  Canvas.Polygon(Poly);
end;

我想要的是这个,但是不同的是Point[1]Point[2]等由用户使用MouseEvent给出。


4
问题是什么? - Uwe Raabe
处理OnClick事件并将该点添加到点列表中。 - David Heffernan
问题是,我如何在onclick事件中将点存储在数组中? - Fruit
2个回答

4
您可以在图像上叠加一个画盒,并使用以下代码:
你可以将画盒覆盖在你的图片上,然后使用这样的代码:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TPointArray=array of TPoint;
  TForm3 = class(TForm)
    Image1: TImage;
    PaintBox1: TPaintBox;
    Button1: TButton;
    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure PaintBox1Paint(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    FPointArray:TPointArray;
  public
    { Public-Deklarationen }
  end;
var
  Form3: TForm3;
implementation
{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
   PaintBox1.Visible := false;
   Image1.Canvas.Polygon(FPointArray);
end;

procedure TForm3.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   SetLength(FPointArray,Length(FPointArray)+1);
   FPointArray[High(FPointArray)].X := X;
   FPointArray[High(FPointArray)].Y := Y;
   Paintbox1.Invalidate;
end;

procedure TForm3.PaintBox1Paint(Sender: TObject);
var
 i:Integer;
begin
  PaintBox1.Canvas.Brush.Style := bsClear; //as suggested by TLama
  PaintBox1.Canvas.Polygon(FPointArray);
  for I := 0 to High(FPointArray) do
      begin
        PaintBox1.Canvas.TextOut(FPointArray[i].X-5,FPointArray[i].y-5,IntToStr(i));
      end;
end;

end.

你好,Bummi。我真的很喜欢你的想法。我不得不声明FPointArray:TPointArray;为FPointArray : array of Tpoint。项目运行良好,但是如何使多边形不填充其区域?只需沿着点绘制线条即可? - Fruit
在我看来,这是一个更好的方法。虽然我会在TPaintBox.OnPaint事件中自己渲染TImage图片并移除该TImage组件。如果您想要绘制一个空的多边形,在调用此处的Polygon函数之前,请加入PaintBox1.Canvas.Brush.Style := bsClear;一行代码。 [+1] - TLama
1
@TLama,我也更喜欢仅使用TPaintbox。但是可能Fruit希望在完成所有步骤后保留结果。 - bummi

2
在您的表单中创建一个由点组成的数组。在表单类中声明一个动态数组字段:
private
  FPoly: array of TPoint;

在你的 OnClick 事件中,扩展数组并将一个新坐标附加到其中:
procedure TFruitForm.ImageClick(Sender: TObject);
var
  p: TPoint;
begin
  p := ...;
  SetLength(FPoly, Length(FPoly) + 1);
  FPoly[High(FPoly)] := p;
end;

要为p分配值,请参阅如何在单击控件时获取鼠标坐标?

您还可以考虑使用通用列表TList<TPoint>,而不是数组。


谢谢回复,但是我不需要将点也绘制在图像上吗?我已经将p := ScreenToClient(p)赋值了。 - Fruit
是的,您需要绘制这些点,但这不是您问题的关键。您问道:“如何在单击事件中将点存储在数组中?”显然,您不会想在OnClient事件中绘制多边形,因为在知道所有点之前,您无法绘制整个多边形。 - Rob Kennedy
是的,将它们存储起来,然后在按钮或其他控件中绘制...当我存储点时,在鼠标单击事件中,如果我能看到这些点的位置,那不是更好吗? - Fruit
是的,我想这样做会更好。随意以那种方式编写你的程序。 - Rob Kennedy
在这里+1以平衡我在另一篇帖子中的赞同,因为这个回答the question,而另一篇帖子提供了更好的方法。 - TLama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接