Search code examples
delphipaintfiremonkey

More efficient copy of parent bound rectangle


I want to copy as efficient as possible the bitmap area behind a TRectangle (in example with red border). This is the boundsrect from the red rectangle in the parent control.

I have this in my Delphi Firemonkey app:

Getting the whole parent surface to a temp parent TBitmap:

 (Parent as TControl).PaintTo(FParentBitmap.Canvas,
            RectF(0, 0, ParentWidth, ParentHeight));

and then later on to copy the rectangle I want:

bmp.CopyFromBitmap(FParentBitmap, BoundsRect, 0, 0);

Of course this is not efficient. I want to copy the rectangle in 1 pass or at least I don't want to paint the whole parent into a temp TBitmap.

Do you know an efficient way? Please tell.

I created a TFrostGlass component which has the complete source in it. You can see/download it over here: https://github.com/Spelt/Frost-Glass

The copy bitmap code is in: FrostGlass.pas


Solution

  • Unfortunately, PaintTo does not allow painting only part of the control. However, as @Rob Kennedy mentioned, you can control where on your target Bitmap the content ends up by modifying the offsets.

    In addition, when calling BeginScene before the call to PaintTo, you can set the ClipRects parameter, which means that only this part of the Canvas will be updated. This is necessary if your target Bitmap is larger than BoundsRect, because otherwise you would also paint the area around it.

    procedure PaintPartToBitmap(Control: TControl; SourceRect, TargetRect: TRect; Bitmap: TBitmap);
      var ClipRects: TClipRects;
          X, Y: Single;
    begin
      ClipRects := [TRectF.Create(TargetRect)];
      if (Bitmap.Canvas.BeginScene(@ClipRects)) then
        try
          X := TargetRect.Left - SourceRect.Left;
          Y := TargetRect.Top - SourceRect.Top;
          Control.PaintTo(Bitmap.Canvas, RectF(X, Y, X + Control.Width, Y + Control.Height));
        finally
          Bitmap.Canvas.EndScene;
        end;
    end;