2017-02-24 34 views
1

我想尽可能高效地复制TRectangle后面的位图区域(以红色边框为例)。这是父控件中红色矩形的边界。更有效的父亲边界矩形副本

我有这个在我的德尔福Firemonkey应用:

获取整个父曲面到临时父TBitmap:

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

再后来就复制我想要的矩形:

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

当然这并不高效。我想通过1遍复制矩形,或者至少我不想将整个父级绘制到临时TBitmap中。

你知道一个有效的方法吗?请告诉。

我创建了一个TFrostGlass组件,它有完整的源代码。你可以看到/在这里下载了:https://github.com/Spelt/Frost-Glass

副本位代码是:FrostGlass.pas

+0

不清楚你想要什么,为什么不imediatly给了bmp.canvas?你也有功能TmyControl.MakeScreenshot – 2017-02-24 20:23:33

+0

谢谢。我更新了这个问题,希望现在清楚。 MakeScreenShot将不起作用,因为控件只绘制红色边框,因此截图仅包含红色边框。 – Edward

+0

用负偏移调用PaintTo?而不是在目标画布上绘制(0,0),画到(-control.Left,-control.Top)。 –

回答

0

不幸的是,PaintTo不允许画只有控制的一部分。不过,正如@Rob Kennedy所提到的那样,您可以通过修改偏移量来控制内容在目标位图上的位置。

另外,在调用PaintTo之前调用BeginScene时,可以设置ClipRects参数,这意味着只有这部分Canvas会被更新。如果您的目标位图大于BoundsRect,则这是必需的,否则您也会在其周围绘制区域。

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

ClipRects的确有很多剃须刀。差不多有50%。修改偏移还不能正常工作。 – Edward

+0

我发布的代码适用于我的测试用例。如果它不适合你,你可能需要发布一些你的代码,否则很难分辨出什么问题。 – DNR

+0

我在模糊组件项目中使用它,我将开源。我预计下周末第一个测试版将发布到github上。我会保持联系。 – Edward