Recent

Author Topic: Doubts about copying an image onto a canvas  (Read 687 times)

simsee

  • Full Member
  • ***
  • Posts: 189
Doubts about copying an image onto a canvas
« on: June 03, 2024, 11:52:44 pm »
I want to copy the contents of a TImage onto a scrollbox canvas. I tried with Canvas.Draw and with Canvas.CopyRect, but I don't see anything in both cases. Here is the code:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     ScrollBox1: TScrollBox;
  16.     procedure FormShow(Sender: TObject);
  17.   private
  18.     Image : TImage;
  19.     DestRect, SourceRect : TRect;
  20.   public
  21.  
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.FormShow(Sender: TObject);
  34. begin
  35.   Image:=TImage.Create(Self);
  36.   Image.Picture.LoadFromFile('project1.ico');
  37.   with SourceRect do
  38.     begin
  39.       Left:=0;
  40.       Top:=0;
  41.       Width:=Image.Picture.Width;
  42.       Height:=Image.Picture.Height;
  43.     end;
  44.   with DestRect do
  45.     begin
  46.       Left:=100;
  47.       Top:=100;
  48.       Width:=Image.Picture.Width;
  49.       Height:=Image.Picture.Height;
  50.     end;
  51.   ScrollBox1.Canvas.Draw(0,0,Image.Picture.Bitmap);             //It does not work
  52.   ScrollBox1.Canvas.CopyRect(DestRect,Image.Canvas,SourceRect); //It does not work
  53. end;
  54.  
  55. end.

Where did I go wrong? Thank you.

wp

  • Hero Member
  • *****
  • Posts: 12310
Re: Doubts about copying an image onto a canvas
« Reply #1 on: June 04, 2024, 01:01:38 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormShow(Sender: TObject);
  2. begin
  3.   ...
  4.   ScrollBox1.Canvas.Draw(0,0,Image.Picture.Bitmap);             //It does not work
  5.   ScrollBox1.Canvas.CopyRect(DestRect,Image.Canvas,SourceRect); //It does not work
  6. end;
Accessing a canvas method in the OnShow event handler is not a good idea. In some operating systems this is strictly forbidden and will crash the application, and with even more tolerant ones the drawing will not be persistent, i.e. when after this event handler the OS requests the Scrollbox to repaint itself again it will not know that it should draw the image...

Golden rule for user graphics: Do drawing operations only in the OnPaint handlers of controls because this is exactly what the control must execute when it should redraw itself:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormShow(Sender: TObject);
  2. begin
  3.   Image:=TImage.Create(Self);
  4.   Image.Picture.LoadFromFile('project1.ico');
  5. end;
  6.  
  7. procedure TForm1.Scrollbox1Paint(Sender: TObject);
  8. var
  9.   SourceRect, DestRect: TRect;     // No need to make them global variables!
  10. begin
  11.   with SourceRect do
  12.     begin
  13.       Left:=0;
  14.       Top:=0;
  15.       Width:=Image.Picture.Width;
  16.       Height:=Image.Picture.Height;
  17.     end;
  18.   with DestRect do
  19.     begin
  20.       Left:=100;
  21.       Top:=100;
  22.       Width:=Image.Picture.Width;
  23.       Height:=Image.Picture.Height;
  24.     end;
  25.   ScrollBox1.Canvas.Draw(0,0,Image.Picture.Bitmap);            // only one of them needed.
  26. //  ScrollBox1.Canvas.CopyRect(DestRect,Image.Canvas,SourceRect);
  27. end;

TRon

  • Hero Member
  • *****
  • Posts: 3176
Re: Doubts about copying an image onto a canvas
« Reply #2 on: June 04, 2024, 01:02:09 am »
Where did I go wrong? Thank you.
you forgot to mention FPC & Lazarus version and platform. Also take note of the remark at the documentation of the scrollbox OnPaint handler.

nvm as I crossed wp's post.
All software is open source (as long as you can read assembler)

simsee

  • Full Member
  • ***
  • Posts: 189
Re: Doubts about copying an image onto a canvas
« Reply #3 on: June 04, 2024, 01:32:37 pm »
Thanks for the reply and sorry for the delay in mine.

Yes, you're right, I knew the rule that you have to draw inside the OnPaint event handler.

In reality my problem (I'm on Windows) was mainly with CopyRect method (I didn't realize, due to my mistake, that Draw method works within OnPaint).

In fact, if I use CopyRect inside OnPaint, as in your code, I get a run time error (see attached screenshot). What's the reason?


 

TinyPortal © 2005-2018