This page is "browser friendly". Make your browser window as wide as you want it. The text will flow nicely for you. It is easier to read in a narrow window. With most browsers, pressing plus, minus or zero while the control key (ctrl) is held down will change the texts size. (Enlarge, reduce, restore to default, respectively.) (This is more fully explained, and there's another tip, at my Power Browsing page.)
Drawing is easy in Lazarus (and Delphi)... once you have a surface to draw on. This tutorial will show you how to create that surface.
I'm going to start with stripped down "do it" instructions which will give you a shell, an app with a (nearly) blank page for doing graphics on.
Further down the page, I explain the basics of using graphics with Lazarus or Delphi.
Open a new application, save it in the usual way.
If you are unsure about something in the guide, had a look at the complete listing of the finished code which appears at the bottom of this webpage.
Put an "image" control on the form. It's final position and size will be adjusted by code in the FormCreate handler, so don't be too fussy about where you place it.
Put the following in the interface section just below the word "private"...
Bitmap:TBitmap; iImageLeft, iImageTop, iImageWidth, iImageHeight:integer;
(You can't, alas, just copy the code wholesale.
Put the following in the OnCreate event handler...
iImageLeft:=50; iImageTop:=10; iImageWidth:=200; iImageHeight:=100; Image1.left:=iImageLeft; Image1.top:=iImageTop; Image1.width:=iImageWidth; Image1.height:=iImageHeight; (*Next, assign bitmap to the image... This had benefits in Delphi... I think it was to do with getting what you see on the screen to survive re-sizings, etc. Some examples of Lazarus graphics on the web take a different approach... they simply put a bitmap directly on the main form. They don't bother with the image... but they also over-ride the built in "Paint" handler to do it. I haven't found problems with my "simpler" approach, at least not under Delphi, and this little Lazarus "demo" program works. For the following to work, you'll need a user defined object called "Bitmap", of type Bitmap (See full sourcecode, below) *) Bitmap:=TBitmap.create;//Create a bitmap object Bitmap.width:=iImageWidth;//Assign dimensions Bitmap.height:=iImageHeight; //In Delphi, bitmap background is white to begin with. Black in Lazarus Bitmap.canvas.pen.color:=clWhite;//1 of 2 lines not needed in Delphi... Bitmap.canvas.Rectangle(0,0,iImageWidth,iImageHeight);//2 of 2 not needed, Delphi Image1.Picture.Graphic:=Bitmap; //Assign the bitmap to the image component
That's the general purpose shell created.
The following also go in the OnCreate event handler, just to demostrate a few Lazarus/ Delphi drawing tools. You don't, of course, need these lines in your program for the drawing surface to be present and correct.
//That's our drawing surface "prepared". //Now do some "tricks" with what we have, and learn // where "the edges" of the drawable area are... //From top left, across top Image1.Picture.Bitmap.canvas.pen.color:=clGreen; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(150,0); //From top left, along left edge Image1.Picture.Bitmap.canvas.pen.color:=clRed; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(0,60); //From bottom right, up right hand edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clBlack; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(iImageWidth-1,40); //From bottom right, left along bottom edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clLime; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(50,iImageHeight-1); //Make an individual pixel black... //Look closely at the screen when you loop for // this... the pixel may be very small Image1.Picture.Bitmap.canvas.pixels[10,20] := clBlack; //Text on a graphic... // A variety of "pen" properties can be set // before calling... Image1.Picture.Bitmap.canvas.textout(10,30,'Hello');
That's it! Save what you have. Compile and run it. You should see some lines.
And a very small black dot, near the upper left of the drawing area. And some text saying "Hello".
Once you have the "shell" app above, if you allow for the fact that the native coordinates run from 0,0 at the upper left, you can use the following. There are various properties you can set beforehand such as the color your "ink" will be, how wide lines will be, what typeface will be used, etc, etc.
But here are the basics, to get you started...
... and that's just for starters.
(If you don't like working from 0,0 at upper left, you can simply create a small function to calculate the coordinate the software needs from the system you want to use.)
The demo in this tutorial will display a window with a TImage component on it, and draw some lines just inside the edges of the image, put a dot on the image, and put "Hello" on it.
Will I never learn? About four hours ago, I was working on something in Delphi. I thought to myself, "I ought to post the essence of that in my Lazarus tutorial pages."(And since I wrote that, about three more hours have gone into just the "trivial" parts of wrapping this up... creating the files to download, updating indices, smoothing rough edges.)
It should have been simple. This page. It was going to be just a simple untested listing showing the core of what follows. I didn't think it needed much explanation.
The core is....
1) Fill the following user defined variables (See full sourcecode, below. Specifically, the "type... private..." block.) The canvas you are going to draw on, in this implementation, has to stay the same size all through the program's execution, but you can re-size the window to smaller than the canvas, and still have what you've drawn "there" when you scroll or make the window larger again.
iImageLeft:=50; iImageTop:=10; iImageWidth:=200; iImageHeight:=100;
2) Execute the following once. I do it in the OnCreate handler for the form...
Image1.left:=iImageLeft; Image1.top:=iImageTop; Image1.width:=iImageWidth; Image1.height:=iImageHeight; (*Next, assign bitmap to the image... This had benefits in Delphi... I think it was to do with getting what you see on the screen to survive re-sizings, etc. Some examples of Lazarus graphics on the web take a different approach... they simply put a bitmap directly on the main form. They don't bother with the image... but they also over-ride the built in "Paint" handler to do it. I haven't found problems with my "simpler" approach, at least not under Delphi, and this little Lazarus "demo" program works. For the following to work, you'll need a user defined object called "Bitmap", of type Bitmap (See full sourcecode, below) *) Bitmap:=TBitmap.create;//Create a bitmap object Bitmap.width:=iImageWidth;//Assign dimensions Bitmap.height:=iImageHeight; //In Delphi, bitmap background is white to begin with. Black in Lazarus Bitmap.canvas.pen.color:=clWhite;//1 of 2 lines not needed in Delphi... Bitmap.canvas.Rectangle(0,0,iImageWidth,iImageHeight);//2 of 2 not needed, Delphi Image1.Picture.Graphic:=Bitmap; //Assign the bitmap to the image component
Once you have your bitmap on your image component, here are some of the drawing "tricks" available to you. the examples also show you where "the edges" are.
You CAN do any of the following as soon as you've done the above. You can do them in the OnCreate handler for the form, for instance. But you can also do them at any later time in the program's execution, so, for instance, new dots, lines, text, etc can appear (or disappear: You erase by "drawing" in white the thing you want gone) in response to user input, readings from sensors, etc.
//From top left, across top Image1.Picture.Bitmap.canvas.pen.color:=clGreen; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(150,0); //From top left, along left edge Image1.Picture.Bitmap.canvas.pen.color:=clRed; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(0,60); //From bottom right, up right hand edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clBlack; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(iImageWidth-1,40); //From bottom right, left along bottom edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clLime; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(50,iImageHeight-1); //Make an individual pixel black... //Look closely at the screen when you loop for // this... the pixel may be very small Image1.Picture.Bitmap.canvas.pixels[10,20] := clBlack; //Text on a graphic... // A variety of "pen" properties can be set // before calling... Image1.Picture.Bitmap.canvas.textout(10,30,'Hello')
Then I weakened, and thought "I'd better just check it really works.
There followed about three hours of confusion. It stemmed mostly from the fact that Lazarus initializes the background of the drawing area with black, whereas Delphi initializes it white. What I wanted to do was probably "working", but I didn't notice it working against the black.
So then I chased off, tried various things.
In the end, I think the Lazarus version (below) and the Delphi version (bottom of page) only differ in that the Lazarus version has the two lines in it to initialize the drawing "page" as white, not black. But at this point, WELL out of time, I'm just listing both WORKING programs as they are...
The following "just works". I put a TImage component called Image1 on the form, apart from creating what you see below. Some of it was started for me by Lazarus, for instance the OnCreate handler's skeleton. (Created via the Object Inspector.)
A zip file containing the sourcecode and an .exe of LDNgraphics1 is available for download. It is 3721kb. The equivalent... nearly identical... Delphi zip was only 161kb. Sigh. But Delphi isn't multi-platform.
unit LDNgraphics1u1; (*Ver 27 Dec 13, 11:06, with extra comment added To go with... https://sheepdogguides.com/lut/lt1Graphics.htm *) {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type { TForm1 } TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); private Bitmap:TBitmap; iImageLeft, iImageTop, iImageWidth, iImageHeight:integer; { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin iImageLeft:=50; iImageTop:=10; iImageWidth:=200; iImageHeight:=100; Image1.left:=iImageLeft; Image1.top:=iImageTop; Image1.width:=iImageWidth; Image1.height:=iImageHeight; (*Next, assign bitmap to the image... This had benefits in Delphi... I think it was to do with getting what you see on the screen to survive re-sizings, etc. Some examples of Lazarus graphics on the web take a different approach... they simply put a bitmap directly on the main form. They don't bother with the image... but they also over-ride the built in "Paint" handler to do it. I haven't found problems with my "simpler" approach, at least not under Delphi, and this little Lazarus "demo" program works.*) Bitmap:=TBitmap.create;//Create a bitmap object Bitmap.width:=iImageWidth;//Assign dimensions Bitmap.height:=iImageHeight; //In Delphi, bitmap background is white to begin with. Black in Lazarus Bitmap.canvas.pen.color:=clWhite;//1 of 2 lines not needed in Delphi... Bitmap.canvas.Rectangle(0,0,iImageWidth,iImageHeight);//2 of 2 not needed, Delphi Image1.Picture.Graphic:=Bitmap; //Assign the bitmap to the image component //That's our drawing surface "prepared". //Now do some "tricks" with what we have, and learn // where "the edges" of the drawable area are... //From top left, across top Image1.Picture.Bitmap.canvas.pen.color:=clGreen; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(150,0); //From top left, along left edge Image1.Picture.Bitmap.canvas.pen.color:=clRed; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(0,60); //From bottom right, up right hand edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clBlack; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(iImageWidth-1,40); //From bottom right, left along bottom edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clLime; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(50,iImageHeight-1); //Make an individual pixel black... //Look closely at the screen when you loop for // this... the pixel may be very small Image1.Picture.Bitmap.canvas.pixels[10,20] := clBlack; //Text on a graphic... // A variety of "pen" properties can be set // before calling... Image1.Picture.Bitmap.canvas.textout(10,30,'Hello'); end; end.
The following "just works" in DELPHI. I put a TImage component called Image1 on the form, apart from creating what you see below. Some of it was started for me in the usual way by Delphi, for instance the OnCreate handler's skeleton. (Created via the Object Inspector.)
A zip file containing the sourcecode and an .exe of LDNgraphics1Delphi is available for download. It is 161kb. The equivalent... nearly identical, in design and function... Lazarus zip was a staggering 3,721kb. Sigh. But Lazarus is multi-platform.
I run the program, and I see a white rectangle within the form, with some lines along parts of edges, a dot, and "Hello".
As I said, I think this differs from "the Lazarus version" only in lacking the two lines during the creation of the image-with-bitmap which fill it with white initially.
unit LDNgraphics1DelphiU1; //Name derived from fact that this is // Delphi equivalent of LDNgraphics1, which // was written to go with... //https://sheepdogguides.com/lut/lt1Graphics.htm (*Quick check of grasp of basic graphics, ver 28 Dec 13.. with tweak here not in downloadable version. Remmed*) interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TLDNgraphics1DelphiF1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); private Bitmap:TBitmap; iImageLeft, iImageTop, iImageWidth, iImageHeight:integer; { Private declarations } public { Public declarations } end; var LDNgraphics1DelphiF1: TLDNgraphics1DelphiF1; implementation {$R *.DFM} procedure TLDNgraphics1DelphiF1.FormCreate(Sender: TObject); begin iImageLeft:=20; iImageTop:=10; iImageWidth:=500; iImageHeight:=300; Image1.left:=iImageLeft; Image1.top:=iImageTop; Image1.width:=iImageWidth; Image1.height:=iImageHeight; Bitmap:=TBitmap.create;//Create a bitmap object Bitmap.width:=iImageWidth;//Assign dimensions Bitmap.height:=iImageHeight; (*Next, assign bitmap to the image... This had benefits in Delphi... I think it was to do with getting what you see on the screen to survive re-sizings, etc. Some examples of Lazarus graphics on the web take a different approach... they simply put a bitmap directly on the main form. They don't bother with the image... but they also over-ride the built in "Paint" handler to do it. I haven't found problems with my "simpler" approach, at least not under Delphi, and this little Lazarus "demo" program works.*) Image1.Picture.Graphic:=Bitmap;//Assign the bitmap to the image component //Start: Bit not in downloadable version... //In Delphi, bitmap background is white to begin with. //Background defaults black in Lazarus. If you want // to change the background color to, say, red, you // can do it with... Bitmap.canvas.pen.color:=clRed; Bitmap.canvas.brush.color:=clRed;//makes for FILLED rectangle Bitmap.canvas.Rectangle(0,0,iImageWidth,iImageHeight); //... end of bit not in downloadable version. //That's our drawing surface "prepared". //Now do some "tricks" with what we have, and learn // where "the edges" of the drawable area are... //From top left, across top Image1.Picture.Bitmap.canvas.pen.color:=clGreen; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(300,0); //From top left, along left edge Image1.Picture.Bitmap.canvas.pen.color:=clRed; Image1.Picture.Bitmap.canvas.moveto(0,0); Image1.Picture.Bitmap.canvas.lineto(0,100); //From bottom right, up right hand edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clBlack; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(iImageWidth-1,50); //From bottom right, left along bottom edge //n.b. the "-1" s Image1.Picture.Bitmap.canvas.pen.color:=clLime; Image1.Picture.Bitmap.canvas.moveto(iImageWidth-1,iImageHeight-1); Image1.Picture.Bitmap.canvas.lineto(50,iImageHeight-1); //Making an individual pixel black... Image1.Picture.Bitmap.canvas.pixels[10,20] := clBlack; //Text on a graphic... // A variety of "pen" properties can be set // before calling... Image1.Picture.Bitmap.canvas.textout(10,30,'Hello'); end;//FormCreate end.
Remember: The code above is DELPHI code. The Lazarus version is at the top of the page.
If this didn't quite get the ideas across for you, maybe try my older tutorial introducing drawing graphics in Delphi? Lazarus graphics seem to match what Delphi did, at least in the basics.
Search across all my sites with the Google search...
Or search just SheepdogGuides.com with the Freefind tool...
|
This search merely looks for the words you enter. It won't answer "Where can I download InpOut32?"
If you visit 1&1's site from here, it helps me. They host my website, and I wouldn't put this link up for them if I wasn't happy with their service. They offer things for the beginner and the corporation.
Page has been tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org. Mostly passes.
....... P a g e . . . E n d s .....