3

最近、私は 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 Canvas は深刻な遅れをとっていました。では、高性能にするためにはどうすればよいのでしょうか。

4

1 に答える 1

1

私のコメントを公式の回答にする: Lumia Imaging SDK を使用してください。SwapChainPanelRenderer でリアルタイム レンダリングに使用すると非常に高速な BlurEffect があります。これについては、 BlurEffect を例として正確に使用した Lumia Imaging SDK 3 で SwapChainPanelRenderer を使用してリアルタイム レンダリングを改善するというブログ記事に書きました。完全なソース コードはGitHubで入手できます。

つまり、blur KernelSize 値が新しいスライダー値に変更されるたびにインスタンスRenderAsyncを呼び出すことになります。SwapChainPanelRenderer

private async void EffectRangeSlider_OnValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
    if (this.renderer != null)
    {
        this.viewModel.blur.KernelSize = (int)e.NewValue;

        await this.renderer.RenderAsync();
    }
}
于 2015-11-09T12:06:29.850 に答える