Recent

Author Topic: Basic canvas drawing  (Read 809 times)

Jonny

  • Full Member
  • ***
  • Posts: 143
Basic canvas drawing
« on: February 08, 2025, 03:30:59 pm »
Basic drawing - especially transparency - in Lazarus still continues to puzzle and confuse me.

I am testing and experimenting but things seem not as simple as expected.

For example:

Form with form colour set to yellow
TImage with align to client
Button to draw on timage canvas as below

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   Image1.Canvas.Ellipse(50,50,200,200);
  4. end;
  5.  

The form starts as yellow, but when clicking the button, the background becomes black.

How can I preserve the transparency of the timage whilst drawing rect, ellipse, text to it?

If someone can explain the logic then I can understand and move on, but currently am just doing test after test after test,

Josh

  • Hero Member
  • *****
  • Posts: 1363
Re: Basic canvas drawing
« Reply #1 on: February 08, 2025, 04:54:56 pm »
Hi

TImage holds a TPicture and handles its own drawing events to render that picture.

Timage.canvas is the visual side of the timage.picture.canvas.

You will get odd results drawing on the timage.canvas when no picture is loaded.


It is always best to draw your additions to any component visual canvas using the onpaint event (if present), that way when ever the canvas is redrawn, via resize,invalidate,refresh,paint. your additions will be redone.

when your drawing or outputting text, make sure you have all the brush/pen/font sent, as the canvas remembers.
so store your old brush and pen setting, do what you want and restore them back.

Using ..Brush.Style:=bsClear, will output text without a background

Code: Pascal  [Select][+][-]
  1. var OldBrush:TBrush;
  2.     OldPen:TPen;
  3.     OldFont:TFont;
  4. begin
  5.   OldBrush:=paintbox1.Canvas.Brush;
  6.   OldPen:=paintbox1.Canvas.Pen;
  7.   OldFont:=paintbox1.Canvas.Font;
  8.   ........
  9.   .......
  10.   paintbox1.Canvas.Brush:=OldBrush;
  11.   paintbox1.Canvas.Pen:=OldPen;
  12.   paintbox1.Canvas.Font:=OldFont;
  13. end;                                
« Last Edit: February 08, 2025, 04:56:57 pm by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Basic canvas drawing
« Reply #2 on: February 08, 2025, 05:51:58 pm »
Ok, a little more confused now... let me try to make sense of that.

TImage needs a picture, so I create and assign one:


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, StdCtrls, Forms, Controls, ExtCtrls, Graphics;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Image1: TImage;
  17.     procedure Button1Click(Sender: TObject);
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     EmptyImage: TCustomImage;
  21.   public
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. procedure TForm1.FormCreate(Sender: TObject);
  32. begin
  33.   // Create an empty picture and assign it to TImage
  34.   EmptyImage := TCustomImage.Create(Self);
  35.   EmptyImage.Width := Image1.Width;
  36.   EmptyImage.Height := Image1.Height;
  37.   EmptyImage.Canvas.Brush.Style := bsClear;
  38.   EmptyImage.Canvas.FillRect(0,0,Image1.Width,Image1.Height);
  39.   Image1.Picture.Assign(EmptyImage.Picture);
  40. end;
  41.  
  42. procedure TForm1.Button1Click(Sender: TObject);
  43. begin
  44.   // Now try drawing something additional to TImage
  45.   Image1.Canvas.Brush.Style := bsSolid;
  46.   Image1.Canvas.Brush.Color := clRed;
  47.   Image1.Canvas.Ellipse(50,50,200,200);
  48. end;
  49.  
  50. end.
  51.  

But now nothing is drawn to the TImage.

Josh

  • Hero Member
  • *****
  • Posts: 1363
Re: Basic canvas drawing
« Reply #3 on: February 08, 2025, 06:34:13 pm »
try using the onpaint event of the timage

Code: Pascal  [Select][+][-]
  1. var
  2.   Form1: TForm1;
  3.  
  4.   DrawElp:Boolean=False;
  5.  
  6. procedure TForm1.Button1Click(Sender: TObject);
  7. begin
  8.   DrawElp:=Not DrawElp; // togglr drawing of elipse
  9.   Image1.Invalidate;
  10. end;
  11.  
  12. procedure TForm1.Image1Paint(Sender: TObject);
  13. begin
  14.   If DrawElp Then
  15.   Begin
  16.     .. set any colors you need
  17.     tImage(sender).Canvas.Ellipse(50,50,100,100);
  18.   end;
  19. end;              
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Basic canvas drawing
« Reply #4 on: February 08, 2025, 06:45:49 pm »
Quote from: Josh
try using the onpaint event of the timage

Thanks. My plan is to save the image to a file. By using my method, I can draw to an image in memory then display it in the timage and save it as required.

But by using the onpaint then I have no access to the image to do other processing or to save it.

Is there another alternative?

Josh

  • Hero Member
  • *****
  • Posts: 1363
Re: Basic canvas drawing
« Reply #5 on: February 08, 2025, 07:42:49 pm »
you can save by copying canvas to png to save ie
can use same for paintbox.

You also have the container TPicture type that is the underlying part of timage, so it has the load/save methods with the supported file formats

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var Bmp: TBitmap;
  3.     Png: TPortableNetworkGraphic;
  4. begin
  5.   Image1.Canvas.Ellipse(50,50,100,100);
  6.   Bmp := TBitmap.Create;
  7.   try
  8.     Bmp.SetSize(Image1.width, Image1.height);
  9.     bmp.Canvas.CopyRect(rect(0,0,Image1.width,Image1.height),Image1.Canvas,rect(0,0,Image1.width,Image1.height));
  10.     Png := TPortableNetworkGraphic.Create;
  11.     try
  12.       Png.Assign(Bmp);
  13.       Png.SaveToFile('m:/mypic.png');
  14.     finally
  15.       Png.Free;
  16.     end;
  17.   finally
  18.     Bmp.Free;
  19.   end;
  20. end;      

Have you looked at TPaintbox?
« Last Edit: February 08, 2025, 07:45:33 pm by Josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Basic canvas drawing
« Reply #6 on: February 08, 2025, 08:19:48 pm »
Thanks @Josh, I shall continue to test - can I assume that the objects you mention can handle transparency alpha channel?

Josh

  • Hero Member
  • *****
  • Posts: 1363
Re: Basic canvas drawing
« Reply #7 on: February 08, 2025, 09:02:39 pm »
Hi

If your after smooth graphics/antialliased etc, then i would suggest the bgrabitmap library, it has very fast low level drawing routines.
You can use bgrabitmap as your off canvas image, do all you processing then copy the canvas of the bgrabitmap back to the component canvas of your choice.

Even though the library is sizeable, it does not have a big impact on your final exe.
BGRAControls is a seperate suite of controls using the BGrabitmap library.
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

majolika

  • Jr. Member
  • **
  • Posts: 73
Re: Basic canvas drawing
« Reply #8 on: February 08, 2025, 09:13:27 pm »
the objects you mention can handle transparency alpha channel?
I double using BGRABitmap! Because in pure LCL transparency with alpha-channel is overcomplicated.
Look at my fresh topic, you'll find a working example with LCL transparency  (in the first post) and BGRABitmap transparency (in the last post).
Lazarus 3.8 (rev lazarus_3_8) FPC 3.2.2 x86_64-win64-win32/win64

Jonny

  • Full Member
  • ***
  • Posts: 143
Re: Basic canvas drawing
« Reply #9 on: February 08, 2025, 09:31:17 pm »
Thank you both. Alas, BGRABitmap is not an option for me. I acknowledge that pure LCL transparency with alpha-channel is indeed overcomplicated, but my programs are 90% there with it. Just need to finish the last few bits. Cheers for the link to the other topic, shall look now.

 

TinyPortal © 2005-2018