如何将遮罩应用于 CompositionBrush

how to apply mask to CompositionBrush

<Grid>
    <Image x:Name="BackgroundImage" Source="/Assets/background.png" />
    <Rectangle x:Name="ClippingRect" Margin="50" Fill="#30f0" />
</Grid>

如何应用 alpha 蒙版或剪贴蒙版,使除矩形以外的所有内容都变得模糊?

我照常做:GraphicsEffect->EffectFactory->Brush->Set to SpriteVisual

 var graphicsEffect = new BlendEffect
 {
     Mode = BlendEffectMode.Multiply,
     Background = new ColorSourceEffect
     {
         Name = "Tint",
         Color = Windows.UI.Color.FromArgb(50,0,255,0),
     },

     Foreground = new GaussianBlurEffect()
     {
         Name = "Blur",
         Source =  new CompositionEffectSourceParameter("Backdrop"),
         BlurAmount = (float)20,
         BorderMode = EffectBorderMode.Hard,
     }
 };

 var blurEffectFactory = _compositor.CreateEffectFactory(graphicsEffect,
     new[] { "Blur.BlurAmount", "Tint.Color" });

 var _brush = blurEffectFactory.CreateBrush();
 _brush.SetSourceParameter("Backdrop", _compositor.CreateBackdropBrush());

 var blurSprite = _compositor.CreateSpriteVisual();
 blurSprite.Size = new Vector2((float)BackgroundImage.ActualWidth, (float)BackgroundImage.ActualHeight);
 blurSprite.Brush = _brush;
 ElementCompositionPreview.SetElementChildVisual(BackgroundImage, blurSprite);

您可以使用以下解决方案,它使用了两次相同的图像。 我将一张用于模糊背景,一张用于剪裁前景。

我们的想法是绘制背景模糊 full-size 并在其上仅使用 Clip 属性 作为前景视觉对象的裁剪区域。

XAML为page/control:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image x:Name="BackgroundImage" Source="/Assets/Purple Tentacle.png" />
    <Image x:Name="ClippedImage" Source="/Assets/Purple Tentacle.png" />
</Grid>

背后的代码:

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        _compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
        _backgroundImageVisual  = ElementCompositionPreview.GetElementVisual(BackgroundImage);

        var graphicEffect   = new BlendEffect
        {
            Mode    = BlendEffectMode.Multiply,
            Background  = new ColorSourceEffect
            {
                Color= Color.FromArgb(50, 0, 255, 0)
            },

            Foreground = new GaussianBlurEffect
            {
                Source = new CompositionEffectSourceParameter("Backdrop"),
                BlurAmount  = 20.0f,
                BorderMode = EffectBorderMode.Hard
            }
        };


        var backdropBrush       = _compositor.CreateBackdropBrush();

        var blurEffectFactory   = _compositor.CreateEffectFactory(graphicEffect);
        _brush                  = blurEffectFactory.CreateBrush();
        _brush.SetSourceParameter("Backdrop", backdropBrush);

        _blurSprite          = _compositor.CreateSpriteVisual();
        _blurSprite.Brush    = _brush;

        ElementCompositionPreview.SetElementChildVisual(BackgroundImage, _blurSprite);

        _foregroundImageVisual  = ElementCompositionPreview.GetElementVisual(ClippedImage);
        _foregroundImageVisual.Clip = _compositor.CreateInsetClip(100, 100, 100, 100);

        SizeChanged += MainPage_SizeChanged;
        MainPage_SizeChanged(this, null);
    }

    private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        _blurSprite.Size    = new Vector2((float) BackgroundImage.ActualWidth, (float) BackgroundImage.ActualHeight);

        // change the clip values here to change the non-blurred region
        _foregroundImageVisual.Clip = _compositor.CreateInsetClip(100, 100, 100, 100);
    }

在创作者更新中,我可以创建从 XamlCompositionBrushBase 派生的 class 并将其应用到 xaml 元素,因此它会进行模糊处理:

<Grid>
    <Image x:Name="BackgroundImage" Source="/Assets/background.png" />
    <Path>
       <Path.Fill>
          <local:BlurTintBrush BlurRadius="5" TintColor="Black" TintOpacity="0.7" />
       </Path.Fill>
       <Path.Data>
           <GeometryGroup>
               <RectangleGeometry x:Name="ImageGeometry" Rect="0,0,1027,768" /
               <RectangleGeometry x:Name="CropGeometry" Rect="50,50,25,25" />
           </GeometryGroup>
       </Path.Data>
    </Path>
</Grid>