最近在学习UWP,想做一个简单的demo,只想生成像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 Canvas严重延迟。 那么,我应该怎么做才能使其具有高性能?
最佳答案
将我的评论作为官方答案:使用 Lumia Imaging SDK。它有一个 BlurEffect,如果用于与 SwapChainPanelRenderer 的实时渲染,速度会非常快。我在我的博客文章中写道 Using SwapChainPanelRenderer to improve real-time rendering in Lumia Imaging SDK 3我以 BlurEffect 为例。完整的源代码是 available on GitHub .
归结为每当模糊 KernelSize 值更改为新的 slider 值时在 SwapChainPanelRenderer
实例上调用 RenderAsync
。
private async void EffectRangeSlider_OnValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
if (this.renderer != null)
{
this.viewModel.blur.KernelSize = (int)e.NewValue;
await this.renderer.RenderAsync();
}
}
关于c# - 如何将实时高斯模糊效果应用于 UWP 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33590321/