UWP中的图像模糊投影效果

3

我希望能够获得Windows视频应用模糊的结果。我使用了带有阴影的图像,但只给阴影一个颜色。是否可以使用win2d或其他工具获得此结果,然后将图像用于DropShadow?

enter image description here

我的 MainPage.xaml:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid x:Name="grid"/>
        <Image x:Name="image" Source="Assets/image.jpg"/>
    </Grid>
</Grid>

我的 MainPage.xaml.cs:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var compositor = ElementCompositionPreview.GetElementVisual(grid).Compositor;
    var spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Size = new Vector2(200, 200);
    var dropShadow = compositor.CreateDropShadow();
    dropShadow.Offset = new Vector3(10, 10, 0);
    dropShadow.BlurRadius = 10;
    dropShadow.Color = Colors.Orange;
    spriteVisual.Shadow = dropShadow;
    ElementCompositionPreview.SetElementChildVisual(grid, spriteVisual);
}

感谢您的帮助。


你能详细说明一下你想要实现的效果吗?你只是想模糊整个画面吗?Windows 视频应用中的模糊是什么? - Sean O'Neil
在Windows电影和电视应用程序中,在个人页面上,当您将鼠标移动到一个项目上时,缩略图(缩略图预览)的阴影背景不是单一颜色,而是来自图像的派生效果。这是我想要实现的效果。 - White55
我明白了,那是一个相当不错的效果。也许可以使用类似于您正在尝试的 Composition API 的方法来实现它,但我不知道具体怎么做。不过,您可以在图像后面放置一个模糊、偏移和部分透明的副本,并且仅在 pointerover 事件发生时才可见。我会将其添加为答案,也许有人会提供更好的使用 Composition API 的解决方案。 - Sean O'Neil
3个回答

1
这应该能帮助你开始创建你想要的效果。你需要使用由Microsoft赞助的UWP Community Toolkit库。它拥有下面你将看到的令人惊叹的动画语法,并在内部使用Composition API。根据你的需要调整模糊、缩放和淡入淡出等参数。
XAML
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center" PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited">
        <Image x:Name="imageBackdrop" Source="Assets/image.jpg" Opacity="0"/>
        <Image x:Name="image" Source="Assets/image.jpg"/>
    </Grid>
</Grid>

C#

using Microsoft.Toolkit.Uwp.UI.Animations;

private void Grid_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{    
  imageBackdrop.Fade(0.5f, 50).Scale(1.1f, 1.1f,0,0,0).Blur(75, 0).Offset(0, 20, 0).Start();
}

private void Grid_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{    
  imageBackdrop.Opacity = 0;
}

编辑:更容易的方法是使用一个容器在XAML中进行缩放。同时,在与模糊效果相同的元素上添加不透明度效果似乎会使模糊效果的模糊程度达到非常低的模糊量。使用类似于这样的东西与不透明度掩码或其他东西结合使用,可以使其变暗并且边缘变得柔和:

private void Grid_PointerEntered(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    var element = imageBackdrop;
    var visual = ElementCompositionPreview.GetElementVisual(element);
    var compositor = visual.Compositor;

    var effect = new GaussianBlurEffect()
    {
        Name = "Blur",
        Source = new CompositionEffectSourceParameter("EffectSource"),
        BlurAmount = 50f,
        BorderMode = EffectBorderMode.Soft,
    };

    var blurEffectFactory = compositor.CreateEffectFactory(effect, new[] { effect.Name + "." + nameof(effect.BlurAmount) });
    var brush = blurEffectFactory.CreateBrush();
    var destinationBrush = compositor.CreateBackdropBrush();
    brush.SetSourceParameter("EffectSource", destinationBrush);

    var sprite = compositor.CreateSpriteVisual();
    sprite.Size = new Vector2((float)(element.RenderSize.Width), (float)(element.RenderSize.Height));
    sprite.Brush = brush;
    ElementCompositionPreview.SetElementChildVisual(element, sprite);
    imageBackdropContainer.Opacity = 1;
}

private void Grid_PointerExited(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    imageBackdropContainer.Opacity = 0;
}

enter image description here


请问您能否插入一张结果图像? - White55
抱歉我没有包括一个可以圆润和柔化边缘的笔刷,所以它看起来非常糟糕。同时,我注意到在将不透明度和模糊应用于同一UIElement时存在某种错误或限制,即使你将其设置得多高,模糊效果也非常微弱。也许将一个效果应用到包围网格中会有所改善。你懂的。据我所知,Compositor.CreateDropShadow()可能不起作用。使用图像的副本并相应地进行过滤。 - Sean O'Neil

1
您可以尝试使用较低的不透明度来偏移相同的图像,以使用CompositionSurfaceBrush实现类似的效果。
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var compositor = ElementCompositionPreview.GetElementVisual(grid).Compositor;
    var spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Size = new Vector2(215, 215);

    var brush = compositor.CreateSurfaceBrush();
    LoadedImageSurface _loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/image.jpg"));
    brush.Surface = _loadedSurface;

    spriteVisual.Opacity = 0.1f;
    spriteVisual.Brush = brush;

    ElementCompositionPreview.SetElementChildVisual(grid, spriteVisual);
}

And this is the effect:

enter image description here


0

Windows Community Toolkit 中的 DropShadowPanel 可以实现您想要的效果。至少我用它来实现了这个功能。然后使用 VisualStateManager 将其可见性设置为 True,当鼠标指针悬停在上面时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接