Recent

Author Topic: Window and Bitmap  (Read 3091 times)

Baggey

  • Newbie
  • Posts: 6
Window and Bitmap
« on: February 18, 2024, 11:40:34 am »
Hi Everyone im new here,  ;)

Im thinking of given Lazarus a whirl. Ive been programming in BlitzMax for a few years now and want faster code.

Sorry if this question has already been asked.

Can anyone tell me how to open a simple window as a bitmap 800,600 and how to directly access the pixels using pointers. I want to write code with out all the windows Gadgets. If that's possible.

I want to make a quick and dirty TV static picture run as fast as possible altering every pixel randomly.

This would help me get started.  %)

Kind Regards Baggey

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #1 on: February 18, 2024, 11:51:47 am »
Hi Baggey:
For something like that (no widgets, direct access to pixels) it is probably much easier/faster to use something like SDL. for more information on SDL see f.e. here.
Today is tomorrow's yesterday.

jamie

  • Hero Member
  • *****
  • Posts: 7492
Re: Window and Bitmap
« Reply #2 on: February 18, 2024, 07:45:54 pm »
I didn't want to wade through the pile of stuff at that site, do you happen to know the min fpc compiler needed ?
The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Window and Bitmap
« Reply #3 on: February 18, 2024, 08:27:19 pm »
Put TImage on your form, make it client aligned.
Put in your Forms class a FBitmap: TBitmap variable.
Whenever needed, create a bitmap via FBitmap := TBitmap.Create and set size to whatever you need, when finished painting do a Image1.Picture.Bitmap.Assign(FBitmap) and not forget to free the FBitmap afterwards to avoid memory leaks.
You can at any time take that bitmap back from Image1, modify it and update Image1.

That is the most easiest way I guess.

For faster Pixel manipulation instead of pixel by pixel would be ScanLine for example.
Or use a 3rd party like BGRABitmap or Bitmap32.
For more speed you should get common to SDL or OpenGL.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #4 on: February 19, 2024, 02:03:21 am »
I didn't want to wade through the pile of stuff at that site, do you happen to know the min fpc compiler needed ?
Nothing to wade about  :)

Tutorial chapter 2 installation for Linux mentions the use of 3.0.4 but the windows version of that page even mentions 3.0.0 and 2.6.4. There is usually nothing special about SDL(2) headers.

@Baggey:
for a static tv picture it is faster not to manipulate individual pixels at runtime rather prepare 3 or 4 images (the quality of randomness gets better the more images you use) with random static and switch (quickly) between these pictures. That way you have room enough (time wise) to for example display a running bar at runtime.
« Last Edit: February 19, 2024, 02:10:34 am by TRon »
Today is tomorrow's yesterday.

Baggey

  • Newbie
  • Posts: 6
Re: Window and Bitmap
« Reply #5 on: February 19, 2024, 09:22:14 am »
Put TImage on your form, make it client aligned.
Put in your Forms class a FBitmap: TBitmap variable.
Whenever needed, create a bitmap via FBitmap := TBitmap.Create and set size to whatever you need, when finished painting do a Image1.Picture.Bitmap.Assign(FBitmap) and not forget to free the FBitmap afterwards to avoid memory leaks.
You can at any time take that bitmap back from Image1, modify it and update Image1.

That is the most easiest way I guess.

For faster Pixel manipulation instead of pixel by pixel would be ScanLine for example.
Or use a 3rd party like BGRABitmap or Bitmap32.
For more speed you should get common to SDL or OpenGL.

As you can imagine i have no idea how to use Lazarus yet. Or the syntax of pascal. You seem to understand what i want to do. Could you rough something together so that i can play with the code, adapt it and get an idea how of how to get going. This is going to be a massive learning curve.   :-[

I will also look at the SDL but as im not familiar with Lazarus i don't really wont to get bogged down with trying other stuff when im not far passed "Hello World" yet!  :'(

Ive ordered a book which im currently waiting for, so i can use that as a reference. As you can imagine getting started with something new is the biggest herdal.

Im also starting with https://www.youtube.com/@LearnWithHuw

Kind Regards Baggey

cdbc

  • Hero Member
  • *****
  • Posts: 2564
    • http://www.cdbc.dk
Re: Window and Bitmap
« Reply #6 on: February 19, 2024, 09:40:41 am »
Hi
While you're waiting...
Have a look here: https://wiki.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines
Lots of good stuff in there  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #7 on: February 19, 2024, 10:52:20 am »
I will also look at the SDL but as im not familiar with Lazarus i don't really wont to get bogged down with trying other stuff when im not far passed "Hello World" yet!  :'(
Fair enough  :)

Quote
As you can imagine i have no idea how to use Lazarus yet. Or the syntax of pascal. You seem to understand what i want to do. Could you rough something together so that i can play with the code, adapt it and get an idea how of how to get going. This is going to be a massive learning curve.   :-[
You have to start somewhere... so I mocked up a quick and dirty (not advisable) example using a TPaintbox (instead of an TImage) with instructions (as comment in the code) for you to follow so that you are able to learn how to copy-paste examples from this forum (and wiki).

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {
  4.   Instructions:
  5.   - create a new lazarus project
  6.   - from the component palette drop onto your form
  7.     - 1 x TPaintbox (don't make it too big but stick to a size of f.e. 320x200)
  8.     - 1 x TTimer
  9.     - 1 x TToggleBox
  10.   - double-click on the form to add a FormCreate event (e.g. TForm1.FormCreate ) in your source-code
  11.   - Add code to the FormCreate event as shown in this source (scroll down)
  12.  
  13.   - the following can be copy-pasted from this source but as alternative also:
  14.     - add the 3 private event methods to the TForm1 declaration above:
  15.       - procedure PaintBox1Paint(Sender: TObject);
  16.       - procedure Timer1Timer(Sender: TObject);
  17.       - procedure ToggleBox1Change(Sender: TObject);
  18.     - make sure your cursor is located inside the code-editor and press ctrl+c to
  19.       let the editor add the missing (private) events (that you just added) to the
  20.       implementation section of your source-code.
  21.     - Make sure the event in your source matches the ones from this source-code
  22.  
  23.   - Save the project
  24.   - Build the project
  25.   - Run the project
  26.   - Press the Togglebox to start/stop animation
  27.   - Note that the paintbos will also update itself when it needs to be
  28.     refreshed due to other (system) events that instruct the paintbox to do so.
  29.   - Have fun !
  30. }
  31.  
  32.  
  33. {$mode objfpc}{$H+}
  34.  
  35. interface
  36.  
  37. uses
  38.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  39.  
  40. type
  41.  
  42.   { TForm1 }
  43.  
  44.   TForm1 = class(TForm)
  45.     PaintBox1: TPaintBox;
  46.     Timer1: TTimer;
  47.     ToggleBox1: TToggleBox;
  48.     procedure FormCreate(Sender: TObject);
  49.   private
  50.     procedure PaintBox1Paint(Sender: TObject);
  51.     procedure Timer1Timer(Sender: TObject);
  52.     procedure ToggleBox1Change(Sender: TObject);
  53.   public
  54.  
  55.   end;
  56.  
  57. var
  58.   Form1: TForm1;
  59.  
  60. implementation
  61.  
  62. {$R *.lfm}
  63.  
  64.  
  65. // see: https://stackoverflow.com/questions/29295229/how-to-seed-to-generate-random-numbers/29296619#29296619
  66. function randomstuff: word;
  67. const
  68.   r0: word = $66;
  69.   r1: word = $5a;
  70.   r2: word = $c3;
  71. begin
  72.   r0 := r0 xor r1 or r2;
  73.   r1 := r1 * r2;
  74.   r2 := r2 + r1;
  75.   r0 := (r0 shl 8) or (r0 shr 8);
  76.   result := r0;
  77. end;
  78.  
  79.  
  80. { TForm1 }
  81.  
  82. procedure TForm1.FormCreate(Sender: TObject);
  83. begin
  84.   PaintBox1.OnPaint   := @PaintBox1Paint;
  85.   PaintBox1.Enabled   := false;
  86.   Timer1.Enabled      := false;
  87.   Timer1.OnTimer      := @Timer1Timer;
  88.   Timer1.Interval     := 42;  // 42 ms = ~24fps
  89.   ToggleBox1.OnChange :=@ToggleBox1Change;
  90. end;
  91.  
  92. procedure TForm1.PaintBox1Paint(Sender: TObject);
  93. var
  94.    x,y: integer;
  95. begin
  96.   for y := 0 to pred(Paintbox1.Canvas.Height) do
  97.     for x := 0 to pred(Paintbox1.Canvas.Width)
  98.       do Paintbox1.Canvas.Pixels[x,y] := $10101 * randomstuff shr 8;
  99. end;
  100.  
  101. procedure TForm1.Timer1Timer(Sender: TObject);
  102. begin
  103.   Paintbox1.Refresh;
  104. end;
  105.  
  106. procedure TForm1.ToggleBox1Change(Sender: TObject);
  107. begin
  108.   Timer1.Enabled := (Sender as TTogglebox).checked;
  109. end;
  110.  
  111. end.
  112.  

Let's see how far you are able to get without getting stuck  :D  (but do post when you get stuck and mention on what you get stuck or where you get stuck exactly)
Today is tomorrow's yesterday.

Baggey

  • Newbie
  • Posts: 6
Re: Window and Bitmap
« Reply #8 on: February 20, 2024, 09:38:50 am »
Ive followed as closely as i can forgive me but i have to start somewhere.  :-[

SOLVED :- Shame i cant post a screen pic of whats going on.

i used File,New and selected application. Adding the Paint box timer and toggle was easy and altering width and height easy. Ive saved file as TVstatic.lpl and then unit1. Then clicked build and run.

Im being met with this message.

Quote
Compile Project, Target: C:\Lazarus_CODE\TVstatic.exe: Exit code 1, Errors: 2, Warnings: 1
unit1.pas(36,4) Warning: Misplaced global compiler switch, ignored
unit1.pas(38,1) Error: Illegal expression
unit1.pas(40,1) Error: Syntax error, ";" expected but "USES" found

I may of misunderstood what to do here :-

- the following can be copy-pasted from this source but as alternative also:
    - add the 3 private event methods to the TForm1 declaration above:
      - procedure PaintBox1Paint(Sender: TObject);
      - procedure Timer1Timer(Sender: TObject);
      - procedure ToggleBox1Change(Sender: TObject);
    - make sure your cursor is located inside the code-editor and press ctrl+c to
      let the editor add the missing (private) events (that you just added) to the
      implementation section of your source-code.

"ctrl+c does nothing?"  :-X

when i double click Form1 cursor is under begin and between end of

Code: Pascal  [Select][+][-]
  1. { TForm1 }
  2.  
  3. procedure TForm1.FormCreate(Sender: TObject);
  4. begin
  5.   {$mode objfpc}{$H+}
  6.  
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  11.  
  12. type
  13.  
  14.   { TForm1 }
  15.  
  16.   TForm1 = class(TForm)
  17.     PaintBox1: TPaintBox;
  18.     Timer1: TTimer;
  19.     ToggleBox1: TToggleBox;
  20.     procedure FormCreate(Sender: TObject);
  21.   private
  22.     procedure PaintBox1Paint(Sender: TObject);
  23.     procedure Timer1Timer(Sender: TObject);
  24.     procedure ToggleBox1Change(Sender: TObject);
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36.  
  37. // see: https://stackoverflow.com/questions/29295229/how-to-seed-to-generate-random-numbers/29296619#29296619
  38. function randomstuff: word;
  39. const
  40.   r0: word = $66;
  41.   r1: word = $5a;
  42.   r2: word = $c3;
  43. begin
  44.   r0 := r0 xor r1 or r2;
  45.   r1 := r1 * r2;
  46.   r2 := r2 + r1;
  47.   r0 := (r0 shl 8) or (r0 shr 8);
  48.   result := r0;
  49. end;
  50.  
  51.  
  52. { TForm1 }
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.   PaintBox1.OnPaint   := @PaintBox1Paint;
  57.   PaintBox1.Enabled   := false;
  58.   Timer1.Enabled      := false;
  59.   Timer1.OnTimer      := @Timer1Timer;
  60.   Timer1.Interval     := 42;  // 42 ms = ~24fps
  61.   ToggleBox1.OnChange :=@ToggleBox1Change;
  62. end;
  63.  
  64. procedure TForm1.PaintBox1Paint(Sender: TObject);
  65. var
  66.    x,y: integer;
  67. begin
  68.   for y := 0 to pred(Paintbox1.Canvas.Height) do
  69.     for x := 0 to pred(Paintbox1.Canvas.Width)
  70.       do Paintbox1.Canvas.Pixels[x,y] := $10101 * randomstuff shr 8;
  71. end;
  72.  
  73. procedure TForm1.Timer1Timer(Sender: TObject);
  74. begin
  75.   Paintbox1.Refresh;
  76. end;
  77.  
  78. procedure TForm1.ToggleBox1Change(Sender: TObject);
  79. begin
  80.   Timer1.Enabled := (Sender as TTogglebox).checked;
  81. end;
  82.  
  83. end.
  84.  
  85. end;
  86.  
  87. end.
  88.                                                      


Kind regards Baggey
« Last Edit: February 20, 2024, 09:49:44 am by Baggey »

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #9 on: February 20, 2024, 09:58:33 am »
I'll lookat the rest of your post later but I made an oops that needs to be corrected right away ...  :-[

"ctrl+c does nothing?"  :-X
That should read: shift+ctrl+c and it might be the cursor in the source-code needs to be located at/in the type definition of the class (the exact location does not matter).

The idea is that when you have defined (custom) methods in a class type definition that you can make the editor automatically create the methods for you in the implementation section.

Apologies in case that caused an issue and/or confused you.
Today is tomorrow's yesterday.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #10 on: February 20, 2024, 10:20:03 am »
Ive followed as closely as i can forgive me but i have to start somewhere.  :-[
Nah that is good. At least you took the courage to actually do it  :)

Something indeed went wrong there. In the end your code in the code editor should exactly look like the code that I posted in my message.

The 'problem' that is probably most confusing when not being familiar is that when you visually design a form that methods (such as TForm1.create) need to be 'linked' inside you form definition file so that the code-editor and the (visual) form are linked together. A lot of technical mumble that might not ring a bell for you but that doesn't matter much at this early stage (you are still learning). But please do note that there is a (invisible) relation/link between the code-editor and your form.

That is reason why I tried to only generate one single event for your first attempt using the form designer. That way only one thing can go wrong (and it did go wrong)  :)

Because I do not know if the link between code-editor and form definition went ok, I think it is best to start from scratch.

- Create a new application project

the source-code in the editor should look like:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.   private
  13.  
  14.   public
  15.  
  16.   end;
  17.  
  18. var
  19.   Form1: TForm1;
  20.  
  21. implementation
  22.  
  23. {$R *.lfm}
  24.  
  25. end.
  26.  

- add the components as you did previous (paintbox, togglebox, timer)

Then the source in the code-editor should look like:
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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     PaintBox1: TPaintBox;
  16.     Timer1: TTimer;
  17.     ToggleBox1: TToggleBox;
  18.   private
  19.  
  20.   public
  21.  
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. end.
  32.  

- on the form editor on the form itself double click so that the Form.Create event is created inside your code-editor.

the code should look like:
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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     PaintBox1: TPaintBox;
  16.     Timer1: TTimer;
  17.     ToggleBox1: TToggleBox;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormCreate(Sender: TObject);
  35. begin
  36.  
  37. end;
  38.  
  39. end.
  40.  
And the code-editor should have the cursor located between the begin and end parts of that event implementation....

Now move the cursor over to the type definition of the class at the private declaration and copy paste so that your code looks like:

(we are adding by means of copy-paste the 3 procedures (methods) named PaintBox1Paint, Timer1Timer and ToggleBox1Change)

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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     PaintBox1: TPaintBox;
  16.     Timer1: TTimer;
  17.     ToggleBox1: TToggleBox;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     procedure PaintBox1Paint(Sender: TObject);
  21.     procedure Timer1Timer(Sender: TObject);
  22.     procedure ToggleBox1Change(Sender: TObject);
  23.   public
  24.  
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.lfm}
  33.  
  34. { TForm1 }
  35.  
  36. procedure TForm1.FormCreate(Sender: TObject);
  37. begin
  38.  
  39. end;
  40.  
  41. end.
  42.  

If you copy-paste the cursor is probably located at the end of the toggleboxchange method. Now press ctrl+shift+c.

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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     PaintBox1: TPaintBox;
  16.     Timer1: TTimer;
  17.     ToggleBox1: TToggleBox;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     procedure PaintBox1Paint(Sender: TObject);
  21.     procedure Timer1Timer(Sender: TObject);
  22.     procedure ToggleBox1Change(Sender: TObject);
  23.   public
  24.  
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.lfm}
  33.  
  34. { TForm1 }
  35.  
  36. procedure TForm1.FormCreate(Sender: TObject);
  37. begin
  38.  
  39. end;
  40.  
  41. procedure TForm1.PaintBox1Paint(Sender: TObject);
  42. begin
  43.  
  44. end;
  45.  
  46. procedure TForm1.Timer1Timer(Sender: TObject);
  47. begin
  48.  
  49. end;
  50.  
  51. procedure TForm1.ToggleBox1Change(Sender: TObject);
  52. begin
  53.  
  54. end;
  55.  
  56. end.
  57.  
  58.  


- now you can copy paste the actual implementations from my example so that it looks the same as the example from my previous post (the order in which the implementated methods appear might be different but that doesn't matter, you can order them any way you want as long as they are located in the implementation section.

Does that help ?
« Last Edit: February 20, 2024, 10:27:16 am by TRon »
Today is tomorrow's yesterday.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Window and Bitmap
« Reply #11 on: February 20, 2024, 10:41:57 am »
The other method to do it (which is shorter):

- create a new application
- add the components (paintbox, timer, togglebox) (becomes part of the link between code and visual design -> .lfm)
- double click the form to create the formcreate event (the invisible link between form designer and code-editor -> .lfm)

Then your code looks like:
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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     PaintBox1: TPaintBox;
  16.     Timer1: TTimer;
  17.     ToggleBox1: TToggleBox;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormCreate(Sender: TObject);
  35. begin
  36.  
  37. end;
  38.  
  39. end.
  40.  

Now, in the editor press ctrl-a to select all text and press delete to delete it (yes completely empty).

then look at the example I posted on the forum using your browser. at the top of the code it reads: "Code: Pascal  [Select]"

press the select link, then press your keyboard ctrl-c (for copy)

Switch back to the Lazarus code editor and press ctrl-v to paste the code inside your editor.

Save the project. Now you should be able to build and run the project.



PS: and yes it is much easier to just attach the project to a post but many examples here on the forums simply paste the Form's unit source-code which then requires to understand how to recreate. Again notice the importance to 'recreate' the invisible link between visual form and code-editor. reason why whenever a project get larger people do tend to attach the example as a complete project but sometimes also by also posting their .lfm file as source).
« Last Edit: February 20, 2024, 10:59:27 am by TRon »
Today is tomorrow's yesterday.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Window and Bitmap
« Reply #12 on: February 20, 2024, 12:31:55 pm »
Put TImage on your form, make it client aligned.
Put in your Forms class a FBitmap: TBitmap variable.
Whenever needed, create a bitmap via FBitmap := TBitmap.Create and set size to whatever you need, when finished painting do a Image1.Picture.Bitmap.Assign(FBitmap) and not forget to free the FBitmap afterwards to avoid memory leaks.
You can at any time take that bitmap back from Image1, modify it and update Image1.

That is the most easiest way I guess.

For faster Pixel manipulation instead of pixel by pixel would be ScanLine for example.
Or use a 3rd party like BGRABitmap or Bitmap32.
For more speed you should get common to SDL or OpenGL.

As you can imagine i have no idea how to use Lazarus yet. Or the syntax of pascal. You seem to understand what i want to do. Could you rough something together so that i can play with the code, adapt it and get an idea how of how to get going. This is going to be a massive learning curve.   :-[

I will also look at the SDL but as im not familiar with Lazarus i don't really wont to get bogged down with trying other stuff when im not far passed "Hello World" yet!  :'(

Ive ordered a book which im currently waiting for, so i can use that as a reference. As you can imagine getting started with something new is the biggest herdal.

Im also starting with https://www.youtube.com/@LearnWithHuw

Kind Regards Baggey
Sure, to start simple, x by y, I've made you a small demo and attached source project.
Since only you know how big the cached bitmap should be and on what positions you want to draw a dot, I've used screen size (image itself does do a stretch draw to always fit)
I try to explain what I do as good as I can:
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, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Button2: TButton;
  17.     Edit1: TEdit;
  18.     Edit2: TEdit;
  19.     Image1: TImage;
  20.     Label1: TLabel;
  21.     Label2: TLabel;
  22.     Panel1: TPanel;
  23.     procedure Button1Click(Sender: TObject);
  24.     procedure Button2Click(Sender: TObject);
  25.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  26.     procedure FormCreate(Sender: TObject);
  27.   private
  28.     FBitmap: TBitmap;
  29.   public
  30.     procedure DrawDot(const ABitmap: TBitmap; const AX, AY, ADotSize: Integer);
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. implementation
  37.  
  38. {$R *.lfm}
  39.  
  40. { TForm1 }
  41.  
  42. procedure TForm1.FormCreate(Sender: TObject);
  43. begin
  44.   // initiate random number generator
  45.   Randomize;
  46.   // create the bitmap to draw on
  47.   FBitmap := TBitmap.Create;
  48.   // make it big
  49.   FBitmap.SetSize(Screen.Width, Screen.Height);
  50.   // choose a background color
  51.   FBitmap.Canvas.Brush.Color := clBtnFace;
  52.   // fill the background
  53.   FBitmap.Canvas.FillRect(0, 0, FBitmap.Width, FBitmap.Height);
  54.   // put it on screen
  55.   Image1.Picture.Bitmap.Assign(FBitmap);
  56.   // generate some random but legit numbers
  57.   Button1Click(Sender);
  58. end;
  59.  
  60. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  61. begin
  62.   FBitmap.Free;
  63. end;
  64.  
  65. procedure TForm1.Button1Click(Sender: TObject);
  66. begin
  67.   // generate random numbers for x and y
  68.   Edit1.Text := IntToStr(Random(FBitmap.Width) + 1);
  69.   Edit2.Text := IntToStr(Random(FBitmap.Height) + 1);
  70. end;
  71.  
  72. procedure TForm1.Button2Click(Sender: TObject);
  73. var
  74.   x, y: Integer;
  75. begin
  76.   // convert values from edit fields to integers
  77.   if TryStrToInt(Edit1.Text, x) then
  78.     if TryStrToInt(Edit2.Text, y) then
  79.       // control that x and y is inside our bitmap range
  80.       if ((x <= FBitmap.Width) and (y <= FBitmap.Height)) then
  81.         // finally call the drawing routine by using a random number for size
  82.         DrawDot(FBitmap, x, y, Random(50) + 1);
  83. end;
  84.  
  85. procedure TForm1.DrawDot(const ABitmap: TBitmap; const AX, AY, ADotSize: Integer);
  86. begin
  87.   // set color
  88.   ABitmap.Canvas.Pen.Color := clBlack;
  89.   ABitmap.Canvas.Brush.Color := clBlack;
  90.   // paint a dot in an individual size
  91.   ABitmap.Canvas.Ellipse(AX - ADotSize div  2, AY - ADotSize div  2, AX + ADotSize div  2, AY + ADotSize div  2);
  92.   // transfer to screen image
  93.   Image1.Picture.Bitmap.Assign(ABitmap);
  94. end;
  95.  
  96. end.
As of right now, user input is needed until you modify the "Button2Click" content to something thats useful for your needs.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

cdbc

  • Hero Member
  • *****
  • Posts: 2564
    • http://www.cdbc.dk
Re: Window and Bitmap
« Reply #13 on: February 20, 2024, 03:02:11 pm »
Hi
@TRon: Nice example mate, cool  8-)
@Baggey: Here's what it could look like when you've finished TRon's excellent example... Quite nifty  ;)
edit: took the screeenshot down again, don't want to spoil the surprise  :D
Regards Benny
« Last Edit: February 20, 2024, 03:04:12 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Baggey

  • Newbie
  • Posts: 6
Re: Window and Bitmap
« Reply #14 on: February 20, 2024, 07:23:51 pm »
Wow! Thankyou everyone, your all so kind :o

This is going to take me a few evenings to get through. :-\

Kind Regards Baggey

 

TinyPortal © 2005-2018