Draw a circle on the Canvas of a TImage with Delphi Firemonekey

Viewed 181

I am trying draw a circle on the TImage canvas in Delphi 11 Firemonkey using the OnMouseDown event of the TImage component. I have written the following code:

procedure TForm1.FormCreate(Sender: TObject);
begin
  // sets the size of the TBitmap
  Image1.Bitmap.SetSize(Round(Image1.Width), Round(Image1.Height));
  Image1.Bitmap.Clear(TAlphaColors.White);
end;


procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
  MyRect: TRectF;
  Point:TPointF;
begin
   // sets the circumscribed rectangle of the ellipse
  Caption:=X.ToString +',' +Y.ToString;
  Point:=TPointF.Create(x,y);
  //Point:=ClientToScreen(Point);
  Point:=Image1.AbsoluteToLocal(Point);
  MyRect := TRectF.Create(Point,5,5);

  // draws the ellipse on the canvas
  Image1.Bitmap.Canvas.BeginScene;
  Image1.Bitmap.Canvas.DrawEllipse(MyRect, 20);
  Image1.Bitmap.Canvas.EndScene;
end;

When I run the app and click on the Timage, the circle is drawn as expected, but not at the exact position, it has an offset away from the mouse pointer. How can I correct this displacement?

enter image description here

1 Answers

The X,Y coordinates provided by the OnMouseDown event are expressed as local coordinates relative to the TImage's client area, they are not expressed as global absolute coordinates. So, you should not be trying to convert Point from absolute coordinates to local coordinates at all, it is already in local coordinates.

You need to remove the call to Image1.AbsoluteToLocal() and just use the coordinates provided as-is, eg:

procedure TForm1.Image1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
  MyRect: TRectF;
  Point: TPointF;
begin
   // sets the circumscribed rectangle of the ellipse
  Caption := X.ToString + ',' + Y.ToString;
  Point := TPointF.Create(X, Y);
  MyRect := TRectF.Create(Point, 5, 5);

  // draws the ellipse on the canvas
  Image1.Bitmap.Canvas.BeginScene;
  Image1.Bitmap.Canvas.DrawEllipse(MyRect, 20);
  Image1.Bitmap.Canvas.EndScene;
end;
Related