2015-11-08 4 views
3

Недавно я изучал UWP и пытался создать простую демоверсию, и я просто хочу создать простой эффект размытия, такой как Aero. Это иногда полезно (светофильтры eg.real времени), так что я сделал идею так:Как применить эффект размытия gaussain для приложений UWP?

Сначала я импортирован библиотеку win2D и поместил CanvasAnimatedControl на RootGrid:

<canvas:CanvasAnimatedControl x:Name="BlurLayer" Draw="BlurLayer_Draw" 
           VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/> 

Ресурс это размытие слой представляет собой рама:

<Frame x:Name="MainFrame" LayoutUpdated="MainFrame_LayoutUpdated" 
     VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/> 

и каждый раз, когда кадр обновляется, MainFrame_LayoutUpdated метод попытаться сохранить ярлык использует RenderTargetBitmap, однако win2D не может получить этот объект в качестве CanvasBitmap, поэтому он преобразуется в байт [] и сохраняется;

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, просто обновить и применить эффект размытия: личного недействительного BlurLayer_Draw (ICanvasAnimatedControl отправитель,

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 был серьезно отложен. Итак, что делать, чтобы сделать его высокопроизводительным?

+0

Возможно, SharpDX может вам помочь? http://sharpdx.org/documentation/api/t-sharpdx-direct2d1-effects-gaussianblur Он использует DirectX и должен быть более эффективным. – sibbl

+0

У меня есть сообщение в блоге о действительно быстрой размытости с Lumia Imaging SDK. Http://igrali.com/2015/09/26/using-swapchainpanelrenderer-to-improve-real-time-rendering-in-lumia-imaging-sdk- 3 /, и проект также находится на GitHub https://github.com/igrali/PropertyDescriptions, возможно, это поможет вам! –

+0

@sibbl Я бы хотел попробовать. – EmbraceZXS

ответ

1

мой комментарий официальный ответ: используйте Lumia Imaging SDK. У этого есть BlurEffect, который действительно быстр, если используется для рендеринга в реальном времени с SwapChainPanelRenderer. Я написал об этом в своем блоге Using SwapChainPanelRenderer to improve real-time rendering in Lumia Imaging SDK 3, где я использовал именно BlurEffect в качестве примера. Полный исходный код: available on GitHub.

При вызове RenderAsync на экземпляр SwapChainPanelRenderer каждый раз, когда значение размытия KernelSize изменяется на новое значение ползунка.

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

     await this.renderer.RenderAsync(); 
    } 
} 
0

Если вы хотите, вы также можете достичь этого эффекта, используя API-интерфейс Composition с обновлением Windows 10 Anniversary. Я написал ответ на аналогичный вопрос here.

+0

это не ответ. Вы должны написать это как комментарий к вопросу или написать полный ответ – Liero