Solved

Canvas.LineTo on TImage very SLOW

Posted on 2002-06-27
6
579 Views
Last Modified: 2010-05-18
Hello, I'm trying to make a tool to get the distance from
a point to another in a map (TImage). I click on the map
then a line moves from that first point to wherever the
mouse moves over the map until the next click.
To do so I make a copy of the original bitmap in another
and copy that one to the TImage after every move of the
mouse to repaint the line to the new position.

This works fine on the comp I'm working, AMD K6-650 with a poor S3 4mb card in windows XP PRO; however I tried
the program in a P3 1Ghz gf2mx200 32mb also in Win xp PRO and it was slow as hell, the new line takes ages to repaint; we tried it as well in our laptop, k6 500 or so and same happened, well it was a bit faster.

Any clue what's happening or a better way to do it ?


Some of the code:

procedure TMaps.DistImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbRight) and DistEnabled then
 begin
  // Finish
  DistEnabled:= False;
  DistImage.Canvas.Draw(0,0,DistImgTmp);
  Label51.Caption:= 'Marque un punto inicial con el ratón sobre el mapa.';
  Label52.Caption:= Format('%d km.',[TotalDist]);
  Exit;
 end;
if (not DistEnabled) and (Button = mbLeft) then // Start Straight Lining
 begin
  DistImage.Canvas.Draw(0,0,DistOrig);
  DistImgTmp.Canvas.Draw(0,0,DistImage.Picture.Graphic);
  TotalDist:= 0;
  DistEnabled:= True;
  DistImgX:= x;
  DistImgY:= y;
  Label51.Caption:= 'Marque los puntos consecuentes del recorrido a medir.'+#13#10+
                      'Para finarlizar puse el boton derecho del ratón.';
  DistImage.Canvas.Brush.Color:= clLime;
  DistImage.Canvas.Brush.Style:= bsDiagCross;
  DistImage.Canvas.Pen.Width:= 3;
  DistImage.Canvas.Pen.Color:= clLime;
  DistImage.Canvas.MoveTo(DistImgX, DistImgY);
  Exit;
 end;
if (DistEnabled) and (Button = mbLeft) then // Next Point
 begin
  DistImgTmp.Canvas.Draw(0,0,DistImage.Picture.Graphic);
  DistImgX:= x;
  DistImgY:= y;
  DistImage.Canvas.MoveTo(DistImgX, DistImgY);
  TotalDist:= TotalDist + Trunc(Ex);
 end;
end;

procedure TMaps.DistImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if DistEnabled then
 begin
  DistImage.Canvas.Draw(0,0,DistImgTmp);
  DistImage.Canvas.MoveTo(DistImgX, DistImgY);
  DistImage.Canvas.LineTo(x,y);
  Ex:= (X-DistImgX) * Escala;
  Ex2:= (Y-DistImgY) * Escala;
  Ex:= sqrt(Ex*Ex+Ex2*Ex2);
  Label52.Caption:= Format('%f km.',[TotalDist + Ex]);
  Label52.Repaint;
 end;
end;
0
Comment
Question by:menorcanet
6 Comments
 
LVL 8

Expert Comment

by:TOndrej
ID: 7113035
You're drawing the whole image on every mousemove... <shudder>
How about leaving the image as is, and using a xor pen to draw the line? (first time xor draws the line, second time it erases)
0
 

Author Comment

by:menorcanet
ID: 7113054
umm, its the first time I'm using the canvas drawing
functions, brushes etc, don't know very well how to
do it properly, could you drop some code ? I can add
more points if needed.

Thanks for your time.
0
 

Expert Comment

by:DirkVerdonck
ID: 7113065
Redrawing the complete bitmap every time is going to cost a lot in performance.  I don't think you're ever gonna make it work acceptably on a standard machine.

What I would try is the following:  have two canvasses, one with the image in it, and one of exactly the same size directly above it, and set to be transparant.  So when you move the mouse, you don't redraw the bitmap, just clear the upper canvas and draw the line again.

Hope this helps...
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 8

Accepted Solution

by:
TOndrej earned 100 total points
ID: 7113110
Just a very quick demo, Image1.Visible is False.

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure Form1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Form1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure Form1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    FLine: array[0..1] of TPoint;
    procedure DrawLine;
  public
  end;

procedure TForm1.DrawLine;
begin
  with Canvas do
  begin
    Pen.Color := clWhite;
    Pen.Mode := pmXor;
    with FLine[0] do
      MoveTo(X, Y);
    with FLine[1] do
      LineTo(X, Y);
  end;
end;

procedure TForm1.Form1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  FLine[0] := Point(X, Y);
end;

procedure TForm1.Form1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if FLine[0].X <> -1 then
  begin
    if FLine[1].X <> -1 then // erase previous line
      DrawLine;
    FLine[1] := Point(X, Y);
    DrawLine; // draw new line
  end;
end;

procedure TForm1.Form1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  DrawLine; // erase previous line
  FLine[0] := Point(-1, -1);
  FLine[1] := Point(-1, -1);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FLine[0] := Point(-1, -1);
  FLine[1] := Point(-1, -1);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Draw(0, 0, Image1.Picture.Graphic);
end;
0
 

Author Comment

by:menorcanet
ID: 7114352
Hello, thanks again. I tried the code and it works nicely!
I will learn from it an adapt it to my current code; I
will make a canvas and jpeg (would it be worth the speed
using a bitmap in stead of jpeg?) in memory.

brb
0
 

Expert Comment

by:S_Warrior
ID: 7230252
Try to draw the line's on the onPaint event.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Syntax Check Delphi Seattle IOS app without MAC ? 1 92
code issue 8 100
Strange behavior when a form is closed 6 51
Delphi IDE crash without error message ... 7 76
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…
As a trusted technology advisor to your customers you are likely getting the daily question of, ‘should I put this in the cloud?’ As customer demands for cloud services increases, companies will see a shift from traditional buying patterns to new…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now