【问题标题】:Draw polygon on Image在图像上绘制多边形
【发布时间】:2013-03-20 21:19:52
【问题描述】:

我已经搜索了很长时间,但无法得到答案。

我想在图像上绘制多边形,但我想通过创建点来实现; 用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 给出的。

【问题讨论】:

  • 问题是什么?
  • 处理 OnClick 事件并将点添加到点列表中。
  • 问题是,如何通过 onclick 事件在 Array 中存储点?

标签: delphi delphi-xe2


【解决方案1】:

您可以在图像上叠加一个 Paintbox 并使用这样的代码

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.

【讨论】:

  • 你好,笨蛋,我真的很喜欢你的想法。我必须声明 FPointArray:TPointArray;作为FPointArray : array of Tpoint。这些项目工作正常,但我如何让它为多边形而不是绘制它的区域?只是沿着点画线?
  • 在我看来这是更好的方法。虽然我会在TPaintBox.OnPaint 事件中自己渲染TImage 图片并删除该TImage 组件。而且,如果您想绘制一个空多边形,请将PaintBox1.Canvas.Brush.Style := bsClear; 行放在此处调用Polygon 函数之前。 [+1]
  • @TLama 我也更喜欢仅使用 TPaintbox。但是,如果所有步骤都完成,possiby Fruit 希望保持结果。
【解决方案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,请参阅How do I get the coordinates of the mouse when a control is clicked?

除了数组,您还可以考虑使用通用列表:TList<TPoint>

【讨论】:

  • 感谢您的回复,但我不需要在图像上绘制点吗?我分配了 p := ScreenToClient(p);
  • 是的,你需要画点,但这不是你的问题。您问:“如何使用 onclick 事件将点存储在 Array 中?”不过,您显然不想在 OnClient 事件中绘制多边形,因为在知道所有点之前您无法绘制整个多边形。
  • 是的,存储它们,然后在我存储点的mouseclick事件中绘制一个按钮或类似的东西,如果我能看到点在哪里不是更好吗?
  • 是的,我想它会更好。随意以这种方式编写您的程序。
  • +1 在这里平衡我对其他帖子的支持,因为这回答了the question,而其他帖子提供了更好的方法。
猜你喜欢
  • 2022-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多