Search code examples
delphifiremonkey

Draw on Canvas with no anti-aliasing effect in Firemonkey


I am trying to make a kind of bitmap editor so I just want to draw a line on a bitmap with no anti-aliasing effect in Firemonkey. Something like this:

var
  Bmp: TBitmap;

Bmp := TBitmap.Create(2000, 2000);
if (Bmp.Canvas.BeginScene) then 
begin
  Bmp.Canvas.Stroke.Color := TAlphaColors.Aquamarine;
  Bmp.Canvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
  Bmp.Canvas.EndScene;
  Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(Bmp);

But it doesn't work. I am trying for a while with several ideas with no luck:

  • Using Map/Unmap to access the bitmap data directly is very slow with big bitmaps according to my coworkers.
  • Using a TImage with DisableInterpolation=true and even GlobalUseGPUCanvas=False doesn't work.
  • Using a TPaintBox component doesn't fit our needs.
  • The solution would be the use of Canvas.Quality=HighPerformance but it's a read-only property. I tried to change the bitmap Canvas.Quality in different ways but it doesn't work.

So how can I simply draw a line with no anti-aliasing effect at all in Firemonkey?

PS: I am using Delphi 10.2.3 (Tokyo)


Solution

  • Finally I found a way to do this. It's so simple that I am wondering if there is some hidden poison in the solution (LOL). TCanvasManager allows the creation of a HighPerformance Canvas from a given bitmap. It draws with no antialiasing according to my tests. Here the code:

    var
      Bmp: TBitmap;
      TmpCanvas: TCanvas;
    begin
      Bmp := TBitmap.Create(2000, 2000);
      TmpCanvas := TCanvasManager.CreateFromBitmap(Bmp, TCanvasQuality.HighPerformance);
      if (TmpCanvas.BeginScene) then
      begin
        TmpCanvas.Stroke.Color := TAlphaColors.Aquamarine;
        TmpCanvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
        TmpCanvas.EndScene;
        Bmp.SaveToFile('c:\temp\result.bmp');
      end;
      FreeAndNil(TmpCanvas);
      FreeAndNil(Bmp);
    

    I also found that it doesn't work with the method to write text on Canvas (Canvas.FillText).

    I hope this helps many others with the same problem.