Как применить маску к CompositionBrush
<Grid>
<Image x:Name="BackgroundImage" Source="/Assets/background.png" />
<Rectangle x:Name="ClippingRect" Margin="50" Fill="#30f0" />
</Grid>
Как применить альфа-маску или обтравочную маску, чтобы все, кроме прямоугольника, было размыто?
Я делаю как обычно: 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);
2 ответа
Решение
В обновлении Creators я могу создать класс, производный от XamlCompositionBrushBase
и применить его к элементу 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>
Вы можете использовать следующее решение, которое использует дважды одно и то же изображение. Я использую один для размытого фона и один для обрезанного переднего плана.
Идея состоит в том, чтобы нарисовать размытый фон в полном размере, а поверх него - только обрезанную область, которую вы хотите, используя свойство Clip для визуального отображения переднего плана.
XAML для страницы / элемента управления:
<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);
}