之前我问过这个问题并删除只是因为1)它似乎比我想做的更多的工作,2)我开始问我的问题很糟糕而且它已经关闭了。但是,经过更多的研究,我决定重新审视这个功能/问题/操作方法
我正在尝试/想要创建一个模糊的叠加层,如下图所示。使用的明显FMX.effect将是“模糊”效果。我的问题是:如何渲染叠加层所覆盖的图像,或者以有效的方式复制图像以模糊叠加层?
我考虑过只使用两个相同的位图,一个用于背景,一个用于模糊但是我不会在原始背景上捕获控件或其他任何内容的“模糊”。我也会认为,如果我要将叠加层滚动到视图之外,那么它就不会像我想要的那样显示/显示。
考虑到上述情况,这一切都让我相信我需要在叠加层滚动/进入视图时动态捕捉背景模糊。如何在Delphi XE6中执行此操作并捕获当前显示的屏幕内容? 不确定从哪里开始。
我没有图片 *
答案 0 :(得分:6)
在对如何捕获父控件背景进行了一些研究之后,我想出了基于FMX的TMagnifierGlass类的以下代码(注意我在XE5中制作了这段代码,你需要检查XE6的兼容性):
TGlass = class(TControl)
private
FBlur: TBlurEffect;
FParentScreenshotBitmap: TBitmap;
function GetSoftness: Single;
procedure SetSoftness(Value: Single);
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
property Softness: Single read GetSoftness write SetSoftness;
end;
{ TGlass }
constructor TGlass.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// Create parent background
FParentScreenshotBitmap := TBitmap.Create(0, 0);
// Create blur
FBlur := TBlurEffect.Create(nil);
FBlur.Softness := 0.6;
end;
destructor TGlass.Destroy;
begin
FBlur.Free;
FParentScreenshotBitmap.Free;
inherited Destroy;
end;
function TGlass.GetSoftness: Single;
begin
Result := FBlur.Softness;
end;
procedure TGlass.SetSoftness(Value: Single);
begin
FBlur.Softness := Value;
end;
procedure TGlass.Paint;
var
ParentWidth: Single;
ParentHeight: Single;
procedure DefineParentSize;
begin
ParentWidth := 0;
ParentHeight := 0;
if Parent is TCustomForm then
begin
ParentWidth := (Parent as TCustomForm).ClientWidth;
ParentHeight := (Parent as TCustomForm).ClientHeight;
end;
if Parent is TControl then
begin
ParentWidth := (Parent as TControl).Width;
ParentHeight := (Parent as TControl).Height;
end;
end;
function IsBitmapSizeChanged(ABitmap: TBitmap; const ANewWidth, ANewHeight: Single): Boolean;
begin
Result := not SameValue(ANewWidth * ABitmap.BitmapScale, ABitmap.Width) or
not SameValue(ANewHeight * ABitmap.BitmapScale, ABitmap.Height);
end;
procedure MakeParentScreenshot;
var
Form: TCommonCustomForm;
Child: TFmxObject;
ParentControl: TControl;
begin
if FParentScreenshotBitmap.Canvas.BeginScene then
try
FDisablePaint := True;
if Parent is TCommonCustomForm then
begin
Form := Parent as TCommonCustomForm;
for Child in Form.Children do
if (Child is TControl) and (Child as TControl).Visible then
begin
ParentControl := Child as TControl;
ParentControl.PaintTo(FParentScreenshotBitmap.Canvas, ParentControl.ParentedRect);
end;
end
else
(Parent as TControl).PaintTo(FParentScreenshotBitmap.Canvas, RectF(0, 0, ParentWidth, ParentHeight));
finally
FDisablePaint := False;
FParentScreenshotBitmap.Canvas.EndScene;
end;
end;
begin
// Make screenshot of Parent control
DefineParentSize;
if IsBitmapSizeChanged(FParentScreenshotBitmap, ParentWidth, ParentHeight) then
FParentScreenshotBitmap.SetSize(Round(ParentWidth), Round(ParentHeight));
MakeParentScreenshot;
// Apply glass effect
Canvas.BeginScene;
try
FBlur.ProcessEffect(Canvas, FParentScreenshotBitmap, FBlur.Softness);
Canvas.DrawBitmap(FParentScreenshotBitmap, ParentedRect, LocalRect, 1, TRUE);
finally
Canvas.EndScene;
end;
end;
要使用,只需在任何控件的基础上实例化TGlass,它应该使所需的"玻璃"你正在寻找的效果
答案 1 :(得分:2)