ali ahmadi
ali ahmadi

Reputation: 189

How to draw FMX.Surface.TBitmapSurface on FMX.Graphics.TBitmap

Follwing on:
How to load large bitmap in FMX (fire monkey)
I have come to a need to draw whats on TBitmapSurface on the FMX.Graphics.TBitmap, i have found a lot of answer regarding this on the web, but they are either in VLC instead of FMX or their goal is saving and loading instead of drawing on a TBitmap, which is why i asked a new question here.
Now here is my current code for loading my image on the TBitmapSurface :

var
  bitmapSurf: TBitmapSurface;
  path: string;
begin
  path := 'image.jpg';
  bitmapSurf := TBitmapSurface.Create;
  TBitmapCodecManager.LoadFromFile(path, bitmapSurf);
end;

Now after searching for a bit i found that i can use Scanline on the TBitmapSurface, but i didn't know how to use it to draw on the TBitmap, on the web some people had used TBitmap.canvas.draw, but such a thing doesn't exist on the FMX!.
In the end my goal is to draw a very large image (1000*16000) which is loaded in the TBitmapSurface on more then 1 TBitmap (because TBitmap doesn't support more then 8192px and my height is 16000px, i need to draw this on two TBitmap).
I am using Delphi 10.2.3.
Thanks.

Upvotes: 1

Views: 2252

Answers (1)

Tom Brunberg
Tom Brunberg

Reputation: 21033

You can split the large image (from a file) to two TImage components as follows

Load the image from file to a TBitmapSurface as you already do in your code.

Then create another TBitmapSurface and set its size to the half of the large one. Copy the first half of the large image to this surface and assign it to Image1.Bitmap. Then copy the latter half to this surface and assign that to Image2.Bitmap.

var
  srce, dest: TBitmapSurface;
  path: string;
  scan: integer;
  w, h1, h2: integer;
begin
  path := 'C:\tmp\Imgs\res.bmp';

  srce := TBitmapSurface.Create;
  try
    TBitmapCodecManager.LoadFromFile(path, srce);

    dest := TBitmapSurface.Create;
    try
      // first half
      w := srce.Width;
      h1 := srce.Height div 2;
      dest.SetSize(w, h1, TPixelFormat.RGBA);
      for scan := 0 to h1-1 do
        Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan]^, srce.Width * 4);
      Image1.Bitmap.Assign(dest);

      // second half
      h2 := srce.Height - h1;
      dest.SetSize(w, h2, TPixelFormat.RGBA);
      for scan := h1 to srce.Height-1 do
        Move(srce.Scanline[scan]^, TBitmapSurface(dest).Scanline[scan-h1]^, srce.Width * 4);
      Image2.Bitmap.Assign(dest);

    finally
      dest.Free;
    end;
  finally
    srce.Free;
  end;

Upvotes: 1

Related Questions