AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FMX Problem bei Textausgabe auf Bitmap

Ein Thema von Rapunzel · begonnen am 9. Jan 2022 · letzter Beitrag vom 9. Jan 2022
Antwort Antwort
Rapunzel

Registriert seit: 1. Mär 2019
48 Beiträge
 
Delphi 11 Alexandria
 
#1

FMX Problem bei Textausgabe auf Bitmap

  Alt 9. Jan 2022, 18:49
Guten Abend,

ich möchte in meiner FMX App eine Graphik zunächst in einer Bitmap als Doublebuffer erstellen und diese dann auf den Canvas einer Paintbox zeichnen. Leider wird der Text aus meiner Bitmap nicht so gestochen scharf auf dem Bildschirm meines Samsung Android Tabletts dargestellt als wenn ich den Text direkt auf den Canvas der Paintbox ausgebe. Ich gehe davon aus, dass es mit dem Skalierungsfaktor 2 zusammenhängt, der auf dem Tablett angewendet wird.

Delphi-Quellcode:
procedure TfrmMain.PtBoxPaint(Sender: TObject; Canvas: TCanvas);
Var Bmp:TBitmap; SrcRc,TxtRc:TRectF;
begin
  Canvas.Font.Size:=30;

  Bmp:=TBitmap.Create(Trunc(PtBox.Width),Trunc(PtBox.Height));
  Bmp.Canvas.BeginScene;
  Bmp.Canvas.Fill.Color:=TAlphaColors.Black;
  Bmp.Canvas.Font.Assign(Canvas.Font);
  TxtRc:=TRectF.Create(10,10,PtBox.Width,PtBox.Height);
  Bmp.Canvas.Stroke.Kind:=TBrushKind.None;
  Bmp.Canvas.FillText(TxtRc, 'Testtest', false, 1, [], TTextAlign.Leading, TTextAlign.Leading);
  Bmp.Canvas.EndScene;
  SrcRc:=TRectF.Create(0,0,Bmp.Width,Bmp.Height);
  Canvas.DrawBitmap(Bmp, SrcRc, SrcRc, 1);

  TxtRc:=TRectF.Create(10,35,PtBox.Width,PtBox.Height);
  Canvas.Fill.Color:=TAlphaColors.Black;
  Canvas.FillText(TxtRc, 'Testtest', false, 1, [], TTextAlign.Leading, TTextAlign.Leading);
  Bmp.Free;
end;
Vielleicht hat ja jemand Zeit und Lust, mir die Lösung des Problems zu verraten.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#2

AW: FMX Problem bei Textausgabe auf Bitmap

  Alt 9. Jan 2022, 20:19
Ein paar Anregungen könnten von hier kommen, z.B. einfach auf einem vergrößertem Bitmap zu malen.

Zitat:
EDIT:

The only option i found for now to remove the antialias is to make the bitmap 2x more bigger and reduce it after by 2x! crazy but the algorithme of reduction remove the aliased ... but the cost of all of this is that the speed become slow, especially when we know that all the graphic function must be done in the main thread

Now more i think more i say to myself that it's crazy to have a graphic library that not support multi-thread ! i can not believe that it's a requirement of openGL and i think now more and more that it's a bug or bad conception in delphi

Speaking about the previous point, even if openGL really required that all graphic routines must be done in the main thread (but really i doubt), i don't understand why delphi not offer on android another TcanvasClass (other than TcanvasGPU) that support multithread ! more crazy is that when you work with TCanvasGPU on Tbitmap, the result will be in any case (as you can see in my previous post) different from what you will have working with TCanvasGPU on the visual component !

now i m looking for function to work directly on pixels grids (old school), that will make me possible to work in multi-thread. but unfortunately their is not to much compatible with firemonley/android

to finish this is the function i use to draw my bitmap. but as this function must be call in the main thread, it's slow down my application (especially the scroll) ... so if you have any idea to make this more fast or multithread i take
Delphi-Quellcode:
    function DrawAdvertBitmap: Tbitmap;
    var aBitmapAliased: Tbitmap;
    begin

      aBitmapAliased := Tbitmap.Create(trunc(FWidth * fScreenScale) * 2, trunc(FHeight * fScreenScale) * 2);

      try

        aBitmapAliased.Canvas.BeginScene;
        try

          aBitmapAliased.canvas.Clear(0);
          aBitmapAliased.canvas.Fill.Color := $ff000000;
          aBitmapAliased.Canvas.Fill.Kind := TbrushKind.Solid;
          aBitmapAliased.Canvas.FillRect(...);

          aBitmapAliased.Canvas.Fill.Color := $ff333844;
          aBitmapAliased.Canvas.Font.Family := 'Roboto-Bold';
          aBitmapAliased.Canvas.Font.Size := 12 * fScreenScale * 2;
          aBitmapAliased.Canvas.Font.Style := [TFontStyle.fsBold];
          aBitmapAliased.Canvas.FillText(...);

        finally
          aBitmapAliased.Canvas.EndScene;
        end;

        //reduce by 2 to make antialiased
        result := Tbitmap.Create(trunc(FWidth * fScreenScale), trunc(FHeight * fScreenScale));

        try

          result.Canvas.BeginScene;
          try

            result.Canvas.Clear(0);
            result.Canvas.DrawBitmap(aBitmapAliased,...);

          finally
            result.Canvas.EndScene;
          end;

        except
          result.Free;
          raise;
        end;

        result.BitmapScale := fScreenScale;

      finally
        aBitmapAliased.free;
      end;

    end;
Zitat:
Answer - 1
0 arrow_circle_up 0 arrow_circle_down

If you are seeing weird anti-aliasing on some controls, I would recommend that you check that the controls do not have fractional position and size values, make sure to use trunc/round on the position or the GPU canvas uses some low-quality interpolation effect on top of any anti-aliasing.

If you plan to do per-pixel manual adjustments, I recommend that you use optimized color-conversion code (scanline <> TAlphaColor) as the built-in code is designed for clear code and not performance: https://github.com/bLightZP/OptimizedDelphiFMXScanline

As for drawing anti-aliased circles with pictures in them, I found the easiest way is to generate an anti-aliased opacity map and apply it to a TImage's TBitmap. You can find code for generating an anti-aliased opacity map here: https://github.com/bLightZP/AntiAliasedCircle
by *

Answer - 2
0 arrow_circle_up 0 arrow_circle_down

If we talk about Firemonkey:

TImage has the property "DisableInterpolation: boolean"
TForm has the property "Quality: TCanvasQuality = (SystemDefault, HighPerformance, HighQuality)" — it is works in design-time

Important to know:

Anti-aliasing is very expensive operation, this is disabled by default on mobile platforms.
The same anti-aliasing should be supported by the device. To Support multisampling the OpenGL must have GL_EXT_multisampled_render_to_texture property. If the device hardware does not support multisampling, the AA will not be.

by *

Answer - 3
0 arrow_circle_up 0 arrow_circle_down

1. Use FMXNativeDraw by OneChen (Aone), - it's very simple, you even do not need to change your standard code for Canvas - need to add only 2 lines (IFDEF). It also supports TPath. It works on 4 platoforms - Win, Mac, Android, iOS. But you need it only on mobile platforms, because antialiasing works on Win and Mac. I use FMXNativeDraw in my mobile projects and it works very well!

Read this article first with google translate about FMXNativeDraw: http://www.cnblogs.com/onechen/p/6350096.html

Download: https://github.com/OneChen/FMXNativeDraw

Btw if you're using PaintBox Canvas - work as usual. If you need to draw on TBitmap Canvas - prepare Bitmap first:

if Scene <> nil then
lScale := Scene.GetSceneScale
else
lScale := 1;

fBitmap.BitmapScale := lScale;
fBitmap.SetSize(Ceil(Width * lScale), Ceil(Height * lScale) );

2. (optional) Also use ZMaterialComponents, that is a wrapper for FMXNativeDraw (circle, rectangle, line etc). You can place these components on a FMX Form as standard TCircle and others. https://github.com/rzaripov1990/ZMaterialComponents
by *

Source: https://stackoverflow.com/questions/34312322
  Mit Zitat antworten Zitat
Rapunzel

Registriert seit: 1. Mär 2019
48 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: FMX Problem bei Textausgabe auf Bitmap

  Alt 9. Jan 2022, 20:58
Vielen Dank, ich konnte mir gerade die Lösung über ein Image mit einer Multiresbitmap erschließen. Auf der Bitmap des Image funktioniert die Textausgabe. Bitmapscale ist das Zauberwort. Hier meine Lösung. Beide Textausgaben sind jetzt 100% identisch

Delphi-Quellcode:
procedure TfrmMain.PtBoxPaint(Sender: TObject; Canvas: TCanvas);
Var Bmp:TBitmap; SrcRc,TxtRc,DstRc:TRectF;
begin
  Canvas.Font.Size:=30;
  Bmp:=TBitmap.Create(1,1);
  Bmp.BitmapScale:=Canvas.Scale;
  // Damit Bmp.Canvas.Scale entsprechend BitmapScale gesetzt wird:
  Bmp.SetSize(Trunc(PtBox.Width*Canvas.Scale),Trunc(PtBox.Height*Canvas.Scale));
  Bmp.Clear(TAlphaColors.White);
  Bmp.Canvas.BeginScene;
  Bmp.Canvas.Fill.Color:=TAlphaColors.Black;
  Bmp.Canvas.Font.Assign(Canvas.Font);
  TxtRc:=TRectF.Create(10,10,PtBox.Width,PtBox.Height);
  Bmp.Canvas.FillText(TxtRc, 'Testtest', false, 1, [], TTextAlign.Leading, TTextAlign.Leading);
  Bmp.Canvas.HorzLine(0,100,50); // Aus Classhelper
  Bmp.Canvas.VertLine(0,100,50); // Aus Classhelper
  Bmp.Canvas.EndScene;
  SrcRc:=TRectF.Create(0,0,Bmp.Width,Bmp.Height);
  DstRc:=TRectF.Create(0,0,PtBox.Width,PtBox.Height);
  Canvas.DrawBitmap(Bmp, SrcRc, DstRc, 1);
  TxtRc:=TRectF.Create(10,35,PtBox.Width,PtBox.Height);
  Canvas.Fill.Color:=TAlphaColors.Black;
  Canvas.FillText(TxtRc, 'Testtest', false, 1, [], TTextAlign.Leading, TTextAlign.Leading);
  Bmp.Free;
end;
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz