Recent

Author Topic: Can't CopyRect in FPC-program  (Read 813 times)

hakelm

  • Full Member
  • ***
  • Posts: 161
Can't CopyRect in FPC-program
« on: September 04, 2025, 08:32:28 am »
Trying to do CopyRect in a simple FPC-program (se below) I get the following error:

Error Project copyk raised exception class 'External: SIGSEGV'. Infile lclintF.inc’ at line 182: Result := WidgetSet.Rawimage_QueryDescription(AFlags,ADesc);
on the line png0.Canvas.CopyRect(r,png1.Canvas,r);.

The same program run as a procedure in a Lazarus application behaves as expected.
What have I missed and what can I do?

Code: Pascal  [Select][+][-]
  1. program copyk;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes
  10.   ,graphics, GraphType
  11.   ;
  12.  
  13. var png0,png1:TPortableNetworkGraphic; r:trect;
  14. begin
  15.    png0:=TPortableNetworkGraphic.Create;
  16.    png0.LoadFromFile('U.png');
  17.  
  18.    png1:=TPortableNetworkGraphic.Create;
  19.    png1.LoadFromFile('k1.png');
  20.    r:=TRect.Create(0, 0, png1.Width, png1.Height);
  21.  
  22.    png0.Canvas.CopyRect(r,png1.Canvas,r);
  23.    png0.SaveToFile('p.png');
  24. end.
  25.  

I have Lazarus Version: 3.8 Date: 2025-08-13 FPC Version: 3.2.2, x86_64-linux-gtk2 on Ubuntu 22.4.
« Last Edit: September 04, 2025, 08:37:33 am by hakelm »

zeljko

  • Hero Member
  • *****
  • Posts: 1792
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Can't CopyRect in FPC-program
« Reply #1 on: September 04, 2025, 09:16:59 am »
Include Interfaces unit

cdbc

  • Hero Member
  • *****
  • Posts: 2467
    • http://www.cdbc.dk
Re: Can't CopyRect in FPC-program
« Reply #2 on: September 04, 2025, 09:18:53 am »
Hi
You are missing one or some of the units, that are present in a GUI app...
My guess would be:
- to include package 'LCLbase' or 'LCL' in you app, /project inspector/
- add 'Interfaces' to your uses-clause...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: Can't CopyRect in FPC-program
« Reply #3 on: September 04, 2025, 09:40:12 am »
Interfaces is enough.
Code: Pascal  [Select][+][-]
  1. program copyk;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   interfaces,
  10.   Classes
  11.   ,graphics, GraphType
  12.   ;
  13.  
  14. var png0,png1:TPortableNetworkGraphic; r:trect;
  15. begin
  16.    png0:=TPortableNetworkGraphic.Create;
  17.    png0.LoadFromFile('U.png');
  18.  
  19.    png1:=TPortableNetworkGraphic.Create;
  20.    png1.LoadFromFile('k1.png');
  21.    r:=TRect.Create(0, 0, png1.Width, png1.Height);
  22.  
  23.    png0.Canvas.CopyRect(r,png1.Canvas,r);
  24.    png0.SaveToFile('p.png');
  25.    png0.free;
  26.    png1.free;
  27. end.
png's must exist.

Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thausand

  • Sr. Member
  • ****
  • Posts: 399
Re: Can't CopyRect in FPC-program
« Reply #4 on: September 04, 2025, 10:01:51 am »
Also can have alternative no use LCL but use TFPImage.

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: Can't CopyRect in FPC-program
« Reply #5 on: September 04, 2025, 11:05:02 am »
Also can have alternative no use LCL but use TFPImage.
Would be good, but does it handle png's?
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thausand

  • Sr. Member
  • ****
  • Posts: 399
Re: Can't CopyRect in FPC-program
« Reply #6 on: September 04, 2025, 11:29:36 am »
Would be good, but does it handle png's?
Yes, can have png when clause uses reader/writer for png (or manual load) https://wiki.freepascal.org/fcl-image#Image_formats

Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. {$mode objfpc}{$h+}
  4.  
  5. uses
  6.   {$ifdef linux}cthreads,{$endif}
  7.   types,sysutils,fpimage,fpcanvas,fpimgcanv,fpreadpng,fpwritepng;
  8.  
  9. procedure copyImgRectToImg(OldFileName,RectFileName,NewFileName:string);
  10. var CompCanvas,RectCanvas:TFPImageCanvas;r:TRect;
  11. begin
  12.   CompCanvas:=TFPImageCanvas.Create(TFPMemoryImage.Create(0,0));
  13.   RectCanvas:=TFPImageCanvas.Create(TFPMemoryImage.Create(0,0));
  14.  
  15.   try
  16.     CompCanvas.Image.LoadFromFile(OldFileName);
  17.     RectCanvas.Image.LoadFromFile(RectFileName);
  18.  
  19.     r:=TRect.Create(0,0,RectCanvas.Image.Width,RectCanvas.Image.Height);
  20.     CompCanvas.CopyRect(0,0,RectCanvas,r);
  21.  
  22.     CompCanvas.Image.SaveToFile(NewFileName);
  23.   finally
  24.     CompCanvas.Free;
  25.     RectCanvas.Free;
  26.   end;
  27. end;
  28.  
  29. // "src.png"  : https://wiki.freepascal.org/images/5/59/splash_logo.png
  30. // "rect.png" : https://wiki.freepascal.org/images/e/ee/LazarusSource.PNG
  31. begin
  32.   copyImgRectToImg('src.png','rect.png','result.png');
  33. end.
  34.  

I think that work.

hakelm

  • Full Member
  • ***
  • Posts: 161
Re: Can't CopyRect in FPC-program
« Reply #7 on: September 04, 2025, 07:13:15 pm »
Thanks all.
fpimage did the trick, se below. Interestingly readers and writers aren't necessary.
But I still can't understand why my original code works in a Lazarus application but not in a non-gui program.

Code: Pascal  [Select][+][-]
  1. program copyk2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes
  10.   ,fpreadpng,fpimage,FPCanvas, FPImgCanv
  11.   ;
  12.  
  13. var r:trect;  png0,png1:TFPCustomImage; canvas0, canvas1 : TFPCustomCanvas; //reader:TFPReaderPNG;
  14.  
  15. begin
  16.    png0:= TFPMemoryImage.Create(10, 10);
  17.    //Reader := TFPReaderpng.Create;
  18.    //png0.LoadFromFile('U.png', Reader);
  19.    png0.LoadFromFile('U.png');
  20.    Canvas0 := TFPImageCanvas.Create(png0);
  21.  
  22.    png1:= TFPMemoryImage.Create(10, 10);
  23.    png1.LoadFromFile('k1.png');
  24.    r:=TRect.Create(1, 1, png1.Width-1, png1.Height-1);
  25.    Canvas1 := TFPImageCanvas.Create(png1);
  26.  
  27.    canvas0.CopyRect(0,0,canvas1,r);
  28.    png0.SaveToFile('p.png');
  29. end.
  30.  

hakelm

  • Full Member
  • ***
  • Posts: 161
Re: Can't CopyRect in FPC-program
« Reply #8 on: September 04, 2025, 07:22:23 pm »
Now I can also confirm that the addition of unit interfaces fixes the problem.

Thausand

  • Sr. Member
  • ****
  • Posts: 399
Re: Can't CopyRect in FPC-program
« Reply #9 on: September 05, 2025, 04:21:41 am »
fpimage did the trick, se below. Interestingly readers and writers aren't necessary.
You have include reader/writer png else no work png. Clause use reader/writer is make work so no have make reader/writer manual (but can make if want or if format not recognize and have explicit reader/writer).

Quote
But I still can't understand why my original code works in a Lazarus application but not in a non-gui program.
Lazarus application have always clause uses interfaces in program project source-code. This not see default with lazarus ide. Please have look source lazarus project <name project>.lpr or have use project/view project source

So when add interfaces for init widget it work because you have now make same as lazarus app that init widget. If ask why need uses interfaces then answer is canvas depend LCL (and TPortableNetworkGraphic depend  graphic, graphic have canvas then all need LCL). Is how is implement TPortableNetworkGraphic.

This why I have make suggest and have use TFPImage because TFPImage not depend widget/LCL. I think is more easy and portable when not display picture and only make manipulate picture. Can have alternative NOGUI widget but that advanced topic (and have same interfaces and depend LCL).
« Last Edit: September 05, 2025, 05:27:31 am by Thausand »

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: Can't CopyRect in FPC-program
« Reply #10 on: September 05, 2025, 07:22:57 am »
But I still can't understand why my original code works in a Lazarus application but not in a non-gui program.
That is because the GUI code has a widgetset registered and your code relies on a registered widget set: you could see that while you were debugging.
Including the interfaces unit registers a widgetset for your platform. It has only two calls:
in the initialization section it calls CreateWidgetSet() and in the finalization it calls FreeWidgetSet().
The other option, using fpimage,  does not need a widgetset and I would prefer that, the example code from Thausand, for smaller console applications.
« Last Edit: September 05, 2025, 07:41:10 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018