Lazarus

Programming => Graphics and Multimedia => Graphics => Topic started by: niotronic on May 16, 2021, 12:38:36 pm

Title: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 16, 2021, 12:38:36 pm
Hi,

I'm using the TImage32, which is part of the graphics32 library and I'm trying to assign a TBitmap to the TImage32.Bitmap, which always results in a totally black screen. On the canvas of the TBitmap32 (=TImage32.Bitmap) however I can draw lines and fill rects without problems. If I assign the TBitmap to a TImage.Bitmap (the standard TImage) the bitmap contained in the original Bitmap is shown correctly. So it's obviously a problem with the TImage32.Bitmap not accepting the standard TBitmap contents ?

Code: Pascal  [Select][+][-]
  1.  
  2. FImage:=TImage32.Create(self);
  3. FImage.Parent:=self;
  4. FImage.Align:=alClient;
  5. FImage.Scale:=1;
  6.  
  7. FImage.Bitmap.Assign(Bitmap);    //shows up as a black screen
  8. FImage.Bitmap.LoadFromFile('/home/arm1/Dokumente/Linux NIO Analyzer  V2-90 - FPC/Graphics/TDIBackground.bmp');    //also shows up as a black screen
  9. FImage.Bitmap.Changed;
  10.  
  11. FImage.Bitmap.Clear(cllime);     //this is shown correctly
  12. FImage.Bitmap.Line(0, 0, 150, 150, clblack, TRUE);  //shown correctly
  13.  
  14.  

Any ideas, what might cause the TImage32 to show any Bitmap assigned as a black screen ?

Best regards

KL
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: winni on May 16, 2021, 01:11:49 pm
Hi!

a)

Code: Pascal  [Select][+][-]
  1. FImage.LoadFromFile('/home/....');

b)
There are a lot of examples in

Code: Text  [Select][+][-]
  1. ct4laz/pl_examples/pl_graphics32/

Winni
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 16, 2021, 07:57:20 pm
Dear Winni,

your suggestion a) is unfortunately not applicable for me since I'm loading the image out of a database via a TStream.

The same code works pretty fine on DELPHI, but when I compile on Lazarus, the TImage32 always shows a black screen after a calling:

FImage.Assign(MyBitmap);

When I for test purposes only assign MyBitmap to a standard TImage it correctly shows the contents of MyBitmap, which prooves that MyBitmap contains correct data.

On the otherhand I can draw on the TImage32 canvas whatever I want and it shows it correctly.

So the problem must be anywhere in the

FImage.Assign(myBitmap)  which obviously cannot deal with the data contained in Mybitmap.

Just to remember: This is working pretty fine on DELPHI...

I'm using Lazarus 1.8.4 and the graphics32 version is 1.9

Any call of FImage.Changed, FImage.ForceFullInvalidate etc. doesn't make it show the contents of MyBitmap...

Best regards,

 KL

Title: Re: Assigning a TBitmap to a TBitmap32
Post by: engkin on May 16, 2021, 08:51:31 pm
The following code works correctly here:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   FImage: TImage32;
  4.   Bitmap: TBitmap;
  5. begin
  6.  FImage:=TImage32.Create(self);
  7.  FImage.Parent:=self;
  8.  FImage.Align:=alClient;
  9.  FImage.Scale:=1;
  10.  
  11.  Bitmap := TBitmap.Create;
  12.  Bitmap.LoadFromFile('c:\Path\To\Some.bmp');
  13.  FImage.Bitmap.Assign(Bitmap);    //Works
  14.  

I am using Win32, Laz2.0.10, GR32 2.0
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 20, 2021, 06:29:57 pm
I tried now to use the latest version of Lazarus (2.1) and of the graphics32 (V1.9 fixed) but unfortunately there hasn't anything changed.
Calling the Assign procedure of TImage32 with a TBitmap as Parameter still results in a black screen - However directly drawing on the Bitmap of the TImage32 works perfectly.
I wrote a small test program which shows this problem...
The whole project is attached.

Attached are also screenshots, one them shows the black screen after pressing "Assign bitmap" - The standard TImage shows the picture correctly, the TImage32 only shows a black screen.
The results of clicking on "Draw on TImage32.Bitmap" is shown in the second picture...


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, GR32_Image,
  9.   ExtCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     Image1: TImage;
  19.     Panel1: TPanel;
  20.     procedure Button1Click(Sender: TObject);
  21.     procedure Button2Click(Sender: TObject);
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure FormDestroy(Sender: TObject);
  24.   private
  25.     FImage32: TImage32;
  26.   public
  27.  
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.Button1Click(Sender: TObject);
  40. var ABitmap: TBitmap;
  41. begin
  42. ABitmap:=TBitmap.create;
  43. try
  44. ABitmap.LoadFromFile('/home/arm1/Downloads/Floorplan2.bmp');
  45. FImage32.Bitmap.Assign(ABitmap);
  46. Image1.Picture.Bitmap.Assign(ABitmap);
  47. finally
  48.   ABitmap.Free;
  49. end;
  50.  
  51. //FImage32.Bitmap.LoadFromFile('/home/arm1/Downloads/Floorplan2.bmp');
  52.  
  53. end;
  54.  
  55. procedure TForm1.Button2Click(Sender: TObject);
  56. begin
  57.   FImage32.Bitmap.Clear(cllime);
  58.   FImage32.Bitmap.Line(10, 10, 200, 200, clblack);
  59.   FImage32.Bitmap.FillRect(140, 40, 180, 80, clblue);
  60. end;
  61.  
  62. procedure TForm1.FormCreate(Sender: TObject);
  63. begin
  64.  FImage32:=TImage32.Create(self);
  65.  FImage32.Align:=alClient;
  66.  FImage32.Parent:=self;
  67. end;
  68.  
  69. procedure TForm1.FormDestroy(Sender: TObject);
  70. begin
  71.   FImage32.Free;
  72. end;
  73.  
  74. end.
  75.  



Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 20, 2021, 06:40:58 pm
Sorry - I forgot to say that the black screen only shows up on Linux X86-64 and Lazarus. The same source code works fine on Windows / DELPHI 10.3...
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: winni on May 20, 2021, 07:09:08 pm
Hi!

Have a look at

https://forum.lazarus.freepascal.org/index.php?topic=49913.0 (https://forum.lazarus.freepascal.org/index.php?topic=49913.0)

Winni

Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 21, 2021, 09:46:54 am
Dear Winni,

the problem discussed at https://forum.lazarus.freepascal.org/index.php?topic=49913.0 is talking about the same problem, but the solutions provided is using a TImage which a TBitmap32 is assigned to. It's not shoing a solutions to the problem with TImage32.bitmap.Assign(Mybitmap).

However I need to use a TImage32 and I'm assining a standard TBitmap.
I did some more tests: Even if I'm using Timage32.Bitmap.LoadFromFile it's only showing a black screen...

Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 21, 2021, 12:31:58 pm
Addendum:
It seems to be a problem with the bitmap format.
When I manually draw something on the TImage32.Bitmap and save this to a *.BMP file I can later on read and show the contents of this file.

Code: Pascal  [Select][+][-]
  1.   FImage:=TImage32.Create(self);
  2.   FImage.Parent:=self;
  3.   FImage.Align:=alClient;
  4.   FImage.ScaleMode:=smStretch;
  5.  
  6.  // FImage.Bitmap.Assign(Bitmap);
  7.  
  8.   FImage.Bitmap.SetSize(600, 400);
  9.   FImage.Bitmap.Clear(cllime32);
  10.   FImage.bitmap.FillRect(10, 10, 60, 60, clblue32);
  11.   FImage.Bitmap.Line(20, 50, 40, 180, clyellow32);
  12.   FImage.Bitmap.FillRect(120, 120, 160, 160, clgreen32);
  13.   FImage.Bitmap.SaveToFile('/home/arm3/Dokumente/Test.bmp', FALSE);
  14.  
  15.   FImage.Bitmap.Clear;
  16.   FImage.Bitmap.LoadFromFile('/home/arm3/Dokumente/Test.bmp');
  17.  

However it obviously swaps the red and blue color channels. Anything that was red before saving to a  *.BMP shows up in blue, anything that was blue shows up in red when it's read from the file...

Does the Timage32.Bitmap use a different internal format ?

Title: Re: Assigning a TBitmap to a TBitmap32
Post by: winni on May 21, 2021, 01:32:13 pm
Hi!

As I told you above for loadFromFile do the same with SaveToFile:

Code: Pascal  [Select][+][-]
  1. var fImage : TImage32;
  2.  
  3. .....
  4. fImage.LoadFromFile;
  5. ...
  6. fImage.SaveToFile;
  7.  

If you don't read the answers then you will always ask the same questions.

Winni

Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 21, 2021, 04:20:28 pm
Dear Winni,

I think we are not talking about the same thing.

First - the original problem was

to Assign a bitmap to Timage32.Bitmap

This is working perfectly on WIN32 with DELPHI.

When I'm running the same code on X86 Linux with Lazarus its resulting in a black screen.
Then started (only to investigate the problem further) with the LoadfromFile and SavetoFile functions:
Result: TImage32  does not show a picture when I call TImage32.Bitmap.Loadfrom file - it's always a black screen.

When I draw something on the TImage32 and Save it to a file then it can be read and shows correctly when I read it again with LoadFromFile

So whats different from any arbitrary *.BMP file compared the *.BMP files which were saved  with the TImage32.SaveToFile procedure ?


But I cannot use LoadfromFile since my picture are read from a Database via a TStream object.

So the one and only question is:

How to assign a TBitmap to the Bitmap32 of a TImage32 and make the Timage32 show the picture

On WIN32 / DELPHI - works like a charm
On X86 Linux /Lazarus - always shows a black screen

Best regards,

KL



Title: Re: Assigning a TBitmap to a TBitmap32
Post by: lucamar on May 21, 2021, 04:46:10 pm
Note that wherever you can SaveTo-/LoadFromFile, there is normally also a SaveTo-/LoadFromStream (which in fact is where saving to and loading from file is actually done, using a TFileStream) so you can omit all the file shenanigans and use the stream read from the database directly.

Though I'm noot sure whether that will work or not, seeing how it's failing with a file. :-[
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: winni on May 21, 2021, 05:40:29 pm
Hi!

I don't get the reason for assigning TBitmap <--> TBitmap32

TBitmap32 is able to handle Transparency.
TBitmap cannot do that.

So whatever you do - you loose the transparency.
Transparency is one of the jobs TBitmap32 can do in opposite to TBitmap.

You cannot assign a cow and hope that it is now a horse.

Winni
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 21, 2021, 05:59:18 pm
Dear Winni,

I'm loading a standard bitmap file out of the database and I want to use this bitmap as the background in a TImage32. I do not want the background picture to be transparent but all the Timager32.layers which I want to show in front of the Background picture.

The problem is that obvisouly the graphics32 library is working as expected on Win32 / DELPHI - I have been using it for years now, but when I started  using it on Linux / Lazarus the TImage32 always shows a black screen - No matter which way I try to load a picture (Assign from a Bitmap, LoadfromFile, Loadfromstream etc. ) it always shows a black screen, and when I manually draw something on the Timage32 (by the use of Fillrect, line arc procedures etc.),  save the Timage32 to a file (TImage32.Bitmap.SavetoFile) and then load it again (TImage32.Bitmap.Loadfromfile) the blue and the red color channels are swapped (a red rectangle before saving show up in blue after Loadfromfile and vice versa)
This is definitely not happening on WIN32 / DELPHI.

I haven't found out yet in which library it's not implemented correctly on the Lazarus / Linux / graphics32, but I will continue to investigate what's causing this malfunctioning with Lazarus / Linux...
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: wp on May 21, 2021, 06:09:18 pm
Can you post a small compilable project along with an image file to demonstrate the issue? It's always better to have some food for the compiler than having to imagine where the issue is.
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: engkin on May 21, 2021, 06:31:35 pm
First of all, can you use the latest version of Graphics32 version 2.0?

It is possible that, after you use LoadFromFile, the result is black. For instance:
Code: Pascal  [Select][+][-]
  1. procedure TCustomBitmap32.LoadFromFile(const FileName: string);
  2. ..
  3.     if (LoadFromBMPStream(FileStream, FileStream.Size)) then
  4.     begin
  5.       Changed;
  6.       exit;
  7.     end;
  8.  

LoadFromBMPStream has to return true. Of course in this same procedure it has more code:
Code: Pascal  [Select][+][-]
  1. {$ifndef COMPILERRX2_UP}
  2.   // Fallback to determing file format based on file type for Delphi 10.1. and older
  3.   // See issue #145
  4.   P := TPicture.Create;
  5.   try
  6.     P.LoadFromFile(FileName);
  7.     Assign(P);
  8.   finally
  9.     P.Free;
  10.   end;
  11. {$endif COMPILERRX2_UP}

The logical thing to do is to debug the code. It might be a missing call to "changed":
Code: Pascal  [Select][+][-]
  1.   FImage.Bitmap.changed;

Or you are using a WS that is not supported or has a bug.

Are you using GTK, GTK2, or CustomDrawn?
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 22, 2021, 07:47:19 am
Please find attached the DELPHI Project
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 22, 2021, 07:48:12 am
This is the Lazarus Project
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: niotronic on May 22, 2021, 07:59:03 am
Would you like to tell me where to get Version 2.0 ? Github and Sourceforge only offer V1.9.1 fixes ?

BR
KL
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: engkin on May 22, 2021, 02:59:56 pm
Ah, I see. I am using the trunk:
Code: Pascal  [Select][+][-]
  1. const
  2.   Graphics32Version = '2.0.0 alpha';

Sorry   :-[
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: wp on May 22, 2021, 04:12:44 pm
Starting with  Windows 10, 64 bit, Laz-trunk/FPC3.2.0 (32 bit): Cloned the GR32 git repository (https://github.com/graphics32/graphics32, master branch). There are two Lazarus packages, a runtime and a designtime package. Compiled the runtime package --> fine. The designtime package is sett up to be installed only (not compiled), thus I rebuilt the IDE --> fails due to "Can't find GR32_Blend used by GR32"; seems to me that this is because the authors put both runtime and designtime units into the same folder... It took me some time until I found a way how to rebuild the IDE again, i forgot the steps.

Fortunately your project creates the TImage32 at runtime, and thus installation is not needed. But your package requirements contain a "GR32_L" package, rather than the GR32_Lazarus of the github package. Replaced it, your program compiles and runs. As expected, of course.

Went on to a VM with Ubuntu 20.04/64 bit. Cloned the repo again. Now even the runtime package refuses to compile, in some assembler part in procedure BlendMems_SS2 in unit GR32_BlendSSE2.... This issue was already posted in https://forum.lazarus.freepascal.org/index.php?topic=53095.0.

Giving up on the master branch, I moved on to the version distributed by OPM: the package now is the Pilot-Logic version, named pl_Graphics32. Compilation fails due to an error in  "Canvas.Brush.Color := clButton" -- this is due to the unknown clButton identifier. I wonder how anybody could compile this... Replacing this by clBtnFace (and, further down the same procedure, the clDisabledButtonText by clGray, and the clButtonText by clWindowText). Next issue is usage of unit Qt5Objects in GR32_Backends_LCL_Qt5 which does not exist, only a QtObjects (my IDE is compiled for qt5 here). Removing the "5" finally makes the package compile.

Testing your program I do see the black area where the bitmap appears on Windows - so, I confirm the issue. Switching to gtk2 widgetset - same issue.

Going to a notebook which has a 32 bit Linux. Now even the git master version compiles (after making the color changes). But in your demo I still see the black area where the Image32 is supposed to be.

Giving up for the moment. To summarize, I confirm the problem that you reported, but it seems to be a Linux issue in general, not just a 64-bit Linux issue as you write. And it is an issue which exists aƶready in the github master version, not only in the PilotLogic version.

It is disappointing to see that the great Graphics32 package essentially is still Windows-only. Compilation issues with undefined identifiers remaining unnoticed indicates that there is little or no maintainance for non-Windows platforms. You should file a bug report on the GR32 github. But I have little hope that this bug will be fixed soon.
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: att2 on May 24, 2021, 12:41:36 pm
I can confirm the issue on a Linux Mint 19 Tara VM with Lazarus 1.8.4 and FPC 3.2.0b1.
When I use the Online Package Manager and when I compile the "pl_Graphics32" libaray, I get the compiling error :

Quote
Compile package pl_Graphics32 7.2.1: Exit code 256, Errors: 1, Hints: 2
Hint: Start of reading config file /home/arm1/fpc2/fpc/bin/x86_64-linux/fpc.cfg
Hint: End of reading config file /home/arm1/fpc2/fpc/bin/x86_64-linux/fpc.cfg
Verbose: Free Pascal Compiler version 3.2.0-beta-r20:39835 [2018/10/17] for aarch64
Verbose: Copyright (c) 1993-2018 by Florian Klaempfl and others
Verbose: Target OS: Linux for AArch64
Verbose: Compiling pl_graphics32.pas
Verbose: Compiling ./source/AllGR32Register.pas
Verbose: Compiling ./source/GR32.pas
/home/arm1/fpc2/config_lazarus/onlinepackagemanager/packages/ct4laz/pl_components/pl_graphics32/source/GR32.inc(48,6) Error: Illegal assembler style specified "INTEL"
Verbose: Compiling ./source/GR32_AllStrings.pas
/home/arm1/fpc2/config_lazarus/onlinepackagemanager/packages/ct4laz/pl_components/pl_graphics32/source/GR32_AllStrings.pas(82,1) Verbose: There were 1 errors compiling module, stopping
Verbose: Compilation aborted
Verbose: /home/arm1/fpc2/fpc/bin/x86_64-linux/ppcrossa64 returned an error exitcode

I am trying to cross-compile for aarch64 in this case. So it seems if I have a project that cross-compiles for a Raspberry-Pi-Clone, I simply cannot do this?



Title: Re: Assigning a TBitmap to a TBitmap32
Post by: wp on May 24, 2021, 01:06:30 pm
It is my impression that Graphics32 works correctly only on Windows, at least unless there is nobody who really takes care of it on other platforms.
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: Handoko on May 24, 2021, 02:28:30 pm
I just tested Graphics32 on Linux. I opened some of the examples, all were buggy on Ubuntu Mate 64-bit.
Title: Re: Assigning a TBitmap to a TBitmap32
Post by: winni on May 24, 2021, 03:36:13 pm
Use BGRAbitmap and BGRAcontrols.

Errors are seldom and quick solved.

Winni
TinyPortal © 2005-2018