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
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;