最近我在学习UWP并尝试构建一个简单的演示,我想要生成一个类似Aero的简单实时模糊效果。它有时很有用(例如实时相机滤镜),所以我想出了以下想法:
首先我导入了win2D库,并在RootGrid上放置了一个CanvasAnimatedControl:
<canvas:CanvasAnimatedControl x:Name="BlurLayer" Draw="BlurLayer_Draw"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
这个模糊层的资源是一个Frame:
<Frame x:Name="MainFrame" LayoutUpdated="MainFrame_LayoutUpdated"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
每次框架更新后,MainFrame_LayoutUpdated方法都会尝试使用RenderTargetBitmap保存快捷方式,但是win2D无法接收此对象作为其CanvasBitmap,因此它被转换为byte[]并保存;
RenderTargetBitmap renderer = new RenderTargetBitmap();
CanvasBitmap bitmap;
byte[] RendererStream;
public static int FrameWidth;
public static int FrameHeight;
public ICanvasImage RenderFinal;
public bool Frame_Updated = false;
private async void MainFrame_LayoutUpdated(object sender, object e)
{
await renderer.RenderAsync(MainFrame);
FrameWidth = renderer.PixelWidth;
FrameHeight = renderer.PixelHeight;
RendererStream = WindowsRuntimeBufferExtensions.ToArray(await renderer.GetPixelsAsync());
if (FrameHeight != 0)
Frame_Updated = true;
}
在
BlurLayer_Draw
方法中,只需刷新并应用模糊效果:
private void BlurLayer_Draw(ICanvasAnimatedControl sender,
CanvasAnimatedDrawEventArgs args)
{
if (Frame_Updated)
{
bitmap = CanvasBitmap.CreateFromBytes(sender, RendererStream, FrameWidth, FrameHeight, DirectXPixelFormat.B8G8R8A8UIntNormalized);
RenderFinal = new GaussianBlurEffect
{
Source = bitmap
};
RenderFinal.BorderMode = EffectBorderMode.Hard;
RenderFinal.BlurAmount = 8.0f;
Frame_Updated = false;
}
if (RenderFinal != null)
args.DrawingSession.DrawImage(RenderFinal);
}
所有的这些都完成后,它可以工作了。 但是这个解决方案真的很糟糕,Win2D 画布严重延迟。 我应该怎么做才能让它高性能?