Recent

Author Topic: [ SOLVED ] Lazarus/FPC FillRect drives me nuts and crazy  (Read 587 times)

jipété

  • Full Member
  • ***
  • Posts: 160
[ SOLVED ] Lazarus/FPC FillRect drives me nuts and crazy
« on: May 26, 2024, 12:03:07 pm »
Hello,

found in an old project, related to TImage :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.btnTestClick(Sender: TObject);
  2. begin
  3.   with Image1.Canvas do begin
  4.     Clear; // ! \\ // ! \\ MANDATORY if not, black display // ! \\
  5.     // http://forum.lazarus.freepascal.org/index.php?topic=12558.0
  6.     Brush.Style := bsSolid;
  7.     Brush.Color := clRed;
  8.     FillRect(0, 0, Width, Height); // ok
  9.     { Save to file }
  10.     image1.Picture.SaveToFile ('test+4params_DrawTest.png'); // ok
  11.   end;
  12. end;

That's ok, but

Code: Pascal  [Select][+][-]
  1. ...
  2.     Brush.Color := clRed;
  3.     FillRect(image1.BoundsRect); // other way, see https://forum.lazarus.freepascal.org/index.php/topic,12558.msg64662.html#msg64662
  4.     { Save to file }
  5.     image1.Picture.SaveToFile ('test+BoundsRect_DrawTest.png'); // NOT ok !
  6.   end;
  7. end;

For BoundsRect, see https://forum.lazarus.freepascal.org/index.php/topic,12558.msg64659.html#msg64659.

I really don't understand...

Have a nice day,
« Last Edit: May 26, 2024, 06:33:05 pm by jipété »

jamie

  • Hero Member
  • *****
  • Posts: 6302
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #1 on: May 26, 2024, 03:41:41 pm »
BoundsRect reports location of image within the parent control.

If you look at the LEFT, TOP of Timage you should see it match the BoundsRect you are getting minus some special border operations.

If the image isn't fully left,top of the parent control, it will report an offset.

also, beware that using the Width,Height of the canvas isn't reliable because it can grow larger than what your drawing surface is.


The only true wisdom is knowing you know nothing

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #2 on: May 26, 2024, 03:50:51 pm »
From what I see two mini lessons, never use TImage to actually draw something and second always use a image format that does do what you want to do and when you finished painting assign it to display control, like TImage.
At least my ruleset is like that. TImage for display, TSomeImage for drawing (TBitmap exemplary)
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #3 on: May 26, 2024, 04:27:02 pm »
Here is your doing in a (for my knowledge) corrected way:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2.   procedure FillTImage(const AImage: TImage; const AColor: TColor);
  3.   var
  4.     LBitmap: TBitmap;
  5.   begin
  6.     LBitmap := TBitmap.Create;
  7.     try
  8.       // to simplify, use controls size
  9.       LBitmap.SetSize(AImage.Width, AImage.Height);
  10.       LBitmap.Canvas.Brush.Style := bsSolid;
  11.       LBitmap.Canvas.Brush.Color := AColor;
  12.       LBitmap.Canvas.FillRect(LBitmap.Canvas.ClipRect);
  13.       AImage.Picture.Assign(LBitmap);
  14.     finally
  15.       LBitmap.Free;
  16.     end;
  17.   end;
  18.   function SaveTImageAsPNG(const AImage: TImage; const AFilename: string): Boolean;
  19.   var
  20.     png: TPortableNetworkGraphic;
  21.   begin
  22.     Result := False;
  23.     // not overwrite files
  24.     if FileExists(AFilename) then
  25.       Exit;
  26.     png := TPortableNetworkGraphic.Create;
  27.     try
  28.       png.Assign(AImage.Picture.Graphic);
  29.       png.SaveToFile(AFilename);
  30.     finally
  31.       png.Free;
  32.     end;
  33.     Result := FileExists(AFilename);
  34.   end;
  35. var
  36.   R, G, B: Byte;
  37. begin
  38.   Randomize;
  39.   R := Random(High(Byte));
  40.   G := Random(High(Byte));
  41.   B := Random(High(Byte));
  42.   FillTImage(Image1, RGBToColor(R, G, B));
  43.   SaveTImageAsPNG(Image1, 'DrawTest.png');
  44. end;
What this code does:
It create and fills a TBitmap with some random color, including its assignment to TImage class
Saves whatever content the TImage got as a PNG file.
I've nested the methods, feel free to re-use elsewhere.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

jipété

  • Full Member
  • ***
  • Posts: 160
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #4 on: May 26, 2024, 06:31:31 pm »
BoundsRect reports location of image within the parent control.
Understood, I'll remove BoundsRect from my mind, thank you.

never use TImage...
So, why not use image1.Picture, like in that example ? :
Code: Pascal  [Select][+][-]
  1. Image1.Picture.Bitmap.LoadFromFile(Application.Location + 'img_sources/cielab_4ico.bmp');
A oneliner which works fine, and easy to remember, for me it's the best !

Thanks for your code, I'll use it for trying to remove TBitmap off my life and use FPImage : too many problems with TBitmap and PixelFormat, for example.

... to actually draw something
And I don't draw, I just ask the system to do that, again, with oneliners.

What this code does:
It create and fills a TBitmap with some random color, including its assignment to TImage class
Saves whatever content the TImage got as a PNG file.
Works fine, thanks a lot !  ;)

+++
Sorry, I cannot add "[ SOLVED ]" to my other topic, the Broken Example, due to limitations from forum,..
« Last Edit: May 26, 2024, 06:36:20 pm by jipété »

wp

  • Hero Member
  • *****
  • Posts: 12069
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #5 on: May 26, 2024, 06:49:43 pm »
Code: Pascal  [Select][+][-]
  1. Image1.Picture.Bitmap.LoadFromFile(Application.Location + 'img_sources/cielab_4ico.bmp');
Better to remember the following code which is much more universal since it works with every registered image format while your code works only with the bmp format:
Code: Pascal  [Select][+][-]
  1. Image1.Picture.LoadFromFile(....);

trying to remove TBitmap off my life and use FPImage
Although I am an absolute friend of fcl-image this is not a good idea. Many things are much easier to achieve with TBitmap than with FPImage. And the associated fcl-image library (and to a lesser extent the IntfGraphics library with TLazIntfImage and TLazCanvas) are not complete: the Pen.Width in the Ellipse or Polygon methods can only be 1, there is no GradientFill, poor region support, and drawing text is quite complicated. No - do not forget TBitmap. Like most things in life, everything has advantages and disadvantages...

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Lazarus/FPC FillRect drives me nuts and crazy
« Reply #6 on: May 26, 2024, 06:52:33 pm »
never use TImage...
So, why not use image1.Picture, like in that example ? :
Code: Pascal  [Select][+][-]
  1. Image1.Picture.Bitmap.LoadFromFile(Application.Location + 'img_sources/cielab_4ico.bmp');
A oneliner which works fine, and easy to remember, for me it's the best !
For such purposes the display class TImage is invented for, you did misunderstood my text.
Code: Pascal  [Select][+][-]
  1. with Image1.Canvas do begin
....I do not say that "with" is worse... damn I said it :-/
You try to manipulate the canvas of the TImage container while "Image1.Picture.Bitmap.LoadFromFile" does load and assign a bitmap file (exact same way as I do by code).
So direct access one graphics format for loading is cool or to simplify "Image1.Picture.LoadFromFile" should be enough to load and display any supported format.
Accessing pixels of TImage.Canvas = just dont.
I hope you understand my meaning and I agree, oneliners are cool but the context where those can be called must fit.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

 

TinyPortal © 2005-2018