c# - 如何将实时高斯模糊效果应用于 UWP 应用程序?

标签 c# uwp win2d

最近在学习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/

相关文章:

c# - Facebook C# SDK + 获取用户的 LIKE

c# - 如何查看用户是否未在 C# 中输入有效条目

c# - 在 UWP Xaml 中创建和填充 NxN 网格

visual-studio-2015 - SpeechRecognizer 无法工作,COMException : Class not registered/UWP App Windows IoT (10. 0.10586) 和 Visual Studio 2015 Update 1

c++ - 如何通过 Win2d 使用顶点着色器

c# - UWP:基于ScrollViewer计算Transformation

c# - LINQ to Entities 无法识别方法 IsNullOrWhiteSpace

c# - 为什么在评估 HMAC 时,我的字节中会出现两个不同的十六进制 'formats'?

c# - 获取StreamSocket的连接状态(UWP)

c# - UWP Composition - 将不透明蒙版应用于 ListView 的顶部 30px