Recent

Author Topic: Q. bgrabitmap newbie: how to reduce the number of units to be used?  (Read 2267 times)

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #15 on: March 09, 2024, 11:11:41 am »
Hi circular, thanks for your replies  :)

Yes, with the dev-core version as from today it’s a big difference (using   BGRABitmap, BGRABitmapTypes, BGRATextFX).  Compilation ok, using of the renderer as mentioned as well!

About $00616161 (a test relict) or ColorToRGB(clBtnFace) as in the wiki sample or clWhatsOEver don’t make an< difference here, and– Yes! – omitting the optional color parameter completely did the trick here. Very good to know that!
Code snippet update would be (compilable and works):

Code: Pascal  [Select][+][-]
  1.   procedure DoDrawTextBgra;
  2.   var  bmp: TBGRABitmap;  renderer: TBGRATextEffectFontRenderer; aLeftOffs: Integer;
  3.   begin
  4.     //bmp := TBGRABitmap.Create(AParent.Width, AParent.Height, ColorToRGB(clBtnFace)); // as Wiki sample. - Would need bmp.FillTransparent
  5.     bmp := TBGRABitmap.Create(AParent.Width, AParent.Height); // Without color parameter
  6.     renderer := TBGRATextEffectFontRenderer.Create;
  7.     bmp.FontRenderer := renderer;
  8.     renderer.ShadowVisible := True;
  9.     renderer.OutlineVisible := True;
  10.     renderer.OutlineColor := BGRABlack;
  11.     renderer.OuterOutlineOnly := True;
  12.     bmp.FontFullHeight := (AFont.Size * 2) - 1;   // 15
  13.     aLeftOffs :=  (Rect.Width -  ACanvas.TextWidth(AText)) Div 2;  // For to achieve text centering
  14.     //bmp.FillTransparent;   // No longer needed - if TBGRABitmap.Create has no color parameter here
  15.     bmp.TextOut(Rect.Left + aLeftOffs, Rect.Top + 2, AText, AFont.Color);
  16.     bmp.Draw(ACanvas, 0, 0, False);   // False = Not opaque
  17.     bmp.Free;
  18.   end;

Big caveat, no space savings:  5.650 instead of 5.651 (full version).
But that has hardly anything to do with the font renderer; if I do only a “uses ..  BGRABitmap, BGRABitmapTypes” without doing any bgra related actions, there will be a result exe as of 5.510.
Did you see basically different results on your side? Mabe i missed something.
Lazarus 3.2  FPC 3.2.2 Win10 64bit

circular

  • Hero Member
  • *****
  • Posts: 4195
    • Personal webpage
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #16 on: March 09, 2024, 02:01:59 pm »
I am glad it compiles now.  :)

Regarding the size, if I compile under MacOS the project test/testcore I get these binary sizes (initially with BGRABITMAP_DONT_USE_LCL and BGRABITMAP_CORE defines):
Code: [Select]
a fully empty program (without any uses)       |  0.4 MB
add uses SysUtils (path of the output image)   |  1.1 MB
add BGRABitmapTypes (all definitions)          |  3.5 MB
add BGRABitmap (an actual bitmap object)       |  4.5 MB
add BGRACanvas (helper canvas)                 |  4.7 MB
add BGRACanvas2d (transform, shadows...)       |  5.2 MB

The big leap when adding BGRABitmapTypes could be reduced (which contains all colorspaces).

The last one, with Canvas2d, does not change much without the "-dBGRABITMAP_CORE" option and is 6.3 MB. The core version is smaller only if one use few features.

From there, to render text, we get extra size depending on the font engine:
Code: [Select]
Vectorized text (pregenerated *.glyphs files)  |  5.6 MB
freetypelaz package (using *.ttf files)        |  9.7 MB
LCL package (without any defines)              | 18.0 MB
By the way, which engine did you use to render text?

I've just put vectorized text in the test/testcore example, if you would like to try. By the way I fixed a bug in the library so you would need to retrieve the latest version. Also I noticed something with the kerning that I am looking into.
Conscience is the debugger of the mind

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #17 on: March 09, 2024, 05:21:45 pm »
Oh. Oh. Maybe I had misleaded myself by a wrong assumption, namely the option particle “-dBGRABITMAP_DONT_USE_LCL” won’t apply to my LCL program. So I maybe had missed the clue by principle.
For test, now included both particles (-dBGRABITMAP_DONT_USE_LCL -dBGRABITMAP_CORE), and picked up the updated dev-core version. Is that ok so  far?

For to compile,  I needed first to comment out the “bmp.Draw(ACanvas, ..)” – “incompatible types”. 
Next steps (following the example):
Introduced a TBGRACanvas object  -   (canvas := TBGRACanvas.Create(bmp); 
Replaced the TBGRATextEffectFontRenderer engine by a TBGRAVectorizedFontRenderer object like in the example testcore.lpr.
->  At bmp.TextOut, runtime exception at  BGRAGraphics TBitmap.GetCanvas

So, still in work, but the size now would be 5.290 MB (instead of 5.650 before).

Experimental status of the snippet:

Code: Pascal  [Select][+][-]
  1.   procedure DoDrawTextBgra;
  2.   var  bmp: TBGRABitmap;   canvas: TBGRACanvas; aLeftOffs: Integer; appdir: String;
  3.        //renderer: TBGRATextEffectFontRenderer;
  4.        renderer: TBGRAVectorizedFontRenderer;
  5.   begin
  6.     appDir := ExtractFilePath(paramStr(0));
  7.     bmp := TBGRABitmap.Create(AParent.Width, AParent.Height); // Without color
  8.     canvas := TBGRACanvas.Create(bmp);  // explicit use of BGRACanvas unit
  9.     //renderer := TBGRATextEffectFontRenderer.Create;
  10.     renderer := TBGRAVectorizedFontRenderer.Create(appDir);
  11.     bmp.FontRenderer := renderer;
  12.     renderer.ShadowVisible := True;
  13.     renderer.OutlineVisible := True;
  14.     renderer.OutlineColor := BGRABlack;
  15.     renderer.OuterOutlineOnly := True;
  16.     bmp.FontFullHeight := (AFont.Size * 2) - 1;   // 15
  17.     aLeftOffs :=  (Rect.Width -  ACanvas.TextWidth(AText)) Div 2;
  18.  
  19.     // ==> Would give exception at BGRAGraphics TBitmap.GetCanvas:
  20.    // bmp.TextOut(Rect.Left + aLeftOffs, Rect.Top + 2, AText, AFont.Color);
  21.  
  22.    // bmp.Draw(ACanvas, 0, 0, False);   // Didn't compile .. different approach
  23.    // ===>  How to draw to the original ACanvas alternatively?
  24.  
  25.     canvas.Free;
  26.     bmp.Free;
  27.   end;

Am I at least somehow on a right direction? Would you see an obvious  mistake, why the TextOut might except?
Lazarus 3.2  FPC 3.2.2 Win10 64bit

circular

  • Hero Member
  • *****
  • Posts: 4195
    • Personal webpage
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #18 on: March 09, 2024, 07:19:20 pm »
Hi d7_2_laz,

Well using LCL depends if you want to draw on a window or on a TBitmap object. If not, then you would just use TBGRABitmap and no call to Draw. I thought you didn't have a GUI, but it seems you want to draw on a TCanvas, so in fact you need the LCL. I don't know what's your use case actually. Can you tell a bit more?

Regarding canvas := TBGRACanvas.Create(bmp); you don't need to do that if you don't use it. Here you call the text functions directly, not through this bridge.

What is the difference between the size without BGRABitmap at all and the call to render text?
Conscience is the debugger of the mind

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #19 on: March 09, 2024, 09:12:40 pm »
Hi circular, many kind thanks again for all your feedbacks!
The actual use case was (driven by another thread here) a toolbar which should have good readability of the button texts, see image from this thread below.It was an experiment.
Actually the control is built ‘handmade’ in a traditional way, but as a kind of bgra-training I could imagine I transfer parts (ie. the gradient drawings) part for part to bgrabitmap (not for reinventing wheels again, but for learning purposes).
The target object of the “DoDrawTextBgra" would be, actually, a custombutton’s TCanvas (but could be a background TBitmap too), on which the caption text is drawn (before the bgra test: via Windows “DrawTextW”).
In so far initially i hadn’t thought about at all to apply a “Not_use_LCL” option …

The initial size of the exe, without bgra, was 4,183 MB, with bgrabitmap full version 5,650;  when omitting font rendering here: 5,510 (neglecticable for me).
The core-only version was not noticeably smaller. Only with the ‘not_use_lcl’  it did sink somehow (5,290 MB).
If I would create now only a renderer object (TBGRAVectorizedFontRenderer), not a bgrabitmap (use clause: only BGRAVectorize), then this would result in 5.036.
Lazarus 3.2  FPC 3.2.2 Win10 64bit

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #20 on: March 10, 2024, 02:58:50 pm »
Hi circular,
For to better talk about the principle, I did a very minimalistic and simplified mini-project. Here, for the moment, for using the full version.
The bgrabitmap files itself are not contained in the zip-file. One might adapt the project's settings appropriately to point to an existing installation.

Lazarus 3.2  FPC 3.2.2 Win10 64bit

circular

  • Hero Member
  • *****
  • Posts: 4195
    • Personal webpage
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #21 on: March 10, 2024, 04:49:30 pm »
Thanks for the additional information and test project. This helps me understand the metric you're using when considering the size of the binaries.

So, I suppose there is not much margin for progress, because text effects use a lot of the features. Still, I will try to see what I can do in the context of your project. I find having a practical example is a great way to identify specific points and view them from a new perspective.
Conscience is the debugger of the mind

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #22 on: March 10, 2024, 07:12:48 pm »
Hi circular, thought so too … don’t worry  …  One won’t hardly be concerned when using this wonderful component(s) (bgracontrols as well !!) more continously in more places in programs. When at creation time they had existed, I’d saved a lot of time and code-lines instead of self-fiddling around  :) :) :)

For to close this for now, the size difference impression between a working core-only version of the simplified mini-test (using -dBGRABITMAP_CORE   ...   but _Not_ “dont_use_lcl”) and the full version actually would be:
2.887.680    project1_without_bgra.exe
4.070.912    project1_core-version.exe
4.397.056    project1_full-version.exe
Lazarus 3.2  FPC 3.2.2 Win10 64bit

circular

  • Hero Member
  • *****
  • Posts: 4195
    • Personal webpage
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #23 on: March 12, 2024, 03:27:19 pm »
Hi d7_2_laz,

By making extended colorspaces optional and not included in the core version, I've reduced on MacOS the size of the binary by half a megabyte.

On Windows, as the binary file is smaller, this makes a smaller difference though. Here are the sizes as units are included:
Code: [Select]
SysUtils          119 Ko
Classes           271 Ko
BGRABitmapTypes   358 Ko
BGRABitmap       1187 Ko
BGRACanvas       1200 Ko
BGRACanvas2d     1446 Ko
BGRAVectorize    1656 Ko
The main jump here is when adding BGRABitmap, because it imports some units, in particular image readers/writers (BMP, PNG), polygon and path rendering. Not sure if it would make sense not import them.

I probably won't make more optimizations in the core version. I will merge into the dev branch later after some more tests.

Thank you for bringing up the issue. I have been considering making BGRABitmap lighter for some time, but never actually got the opportunity to try. I am happy with the result though, for basic image manipulation, it is possible to have BGRABitmap be 916 KB on Windows.  :)

Regards
« Last Edit: March 12, 2024, 03:30:26 pm by circular »
Conscience is the debugger of the mind

d7_2_laz

  • Hero Member
  • *****
  • Posts: 510
Re: Q. bgrabitmap newbie: how to reduce the number of units to be used?
« Reply #24 on: March 12, 2024, 05:49:18 pm »
Hi circular,
and I’m very happy that I didn’t bother but rather met an already existing interest. This is nice to hear!

Just tried the update.

The simple test project has:
2.887.680    project1_without_bgra.exe
4.397.056    project1_full-version.exe
4.070.912    project1_previous_core-version.exe
3.981.824   project1_recent_core-version.exe

For another/real program where I tried to apply, I’d have the following data:

4.748.288  anApp_without_bgra.exe
6.192.640  anApp_bgra_full-version.exe
5.888.000  anApp_core_previous-version.exe
5.799.424  anApp_core_today-version.exe

In sum:
- an app (against the not-bgra-using original) would grow around 1 or 1,1 MB now.
- the recent core version, against the full version, will win approx. 400 KB.
The overhead drops by a third, if I see right.

I’d think that are numbers that sound far better than at the beginning and makes it far easier to apply also when used only for punctual tasks!  :)

Quote
in particular image readers/writers (BMP, PNG), polygon and path rendering. Not sure if it would make sense not import them.

I’d vote Not to exclude them from the core version. The loss of widespread functionality, seen against the benefit, would be surely to high imo. And it would discourage users from using the core version, I’d guess.
Lazarus 3.2  FPC 3.2.2 Win10 64bit

 

TinyPortal © 2005-2018