API de composición de UWP: ¿Esquinas redondeadas?

Nov 19 2020

Estoy luchando por descubrir cómo crear esquinas redondeadas de contenido utilizando Composition API. Aquí es donde estoy, cualquier ayuda sería muy apreciada:

void CreateRoundedCorners(Vector2 cornerRadius, CompositionSurfaceBrush imageSourceBrush, SpriteVisual targetVisual)
{
    CompositionRoundedRectangleGeometry roundedRectangle = _compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = new Vector2(;
    roundedRectangle.CornerRadius = cornerRadius;

    CompositionSpriteShape spriteShape = _compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = _compositor.CreateColorBrush(Colors.Black);
    spriteShape.CenterPoint = new Vector2(_imageSize.X / 2, _imageSize.Y / 2);

    ShapeVisual spriteShapeVisual = _compositor.CreateShapeVisual();
    spriteShapeVisual.Size = _imageSize;
    spriteShapeVisual.Shapes.Add(spriteShape);

    CompositionMaskBrush maskBrush = _compositor.CreateMaskBrush();
    maskBrush.Source = imageSourceBrush;
    maskBrush.Mask = null; // How do I get the rectangle shape in here?

    targetVisual.Brush = maskBrush;
}

Respuestas

1 SeanO'Neil Nov 19 2020 at 13:24

He descubierto una solución. Crear un CompositionVisualSurface, agregarle ShapeVisual y crear un CompositionSurfaceBrush a partir de ese para usarlo como fuente de máscara.

void CreateRoundedCorners(Vector2 cornerRadius, CompositionBrush imageSourceBrush, SpriteVisual targetVisual)
{
    CompositionRoundedRectangleGeometry roundedRectangle =_compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = _imageSize;
    roundedRectangle.CornerRadius = cornerRadius;

    CompositionSpriteShape spriteShape = _compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = _compositor.CreateColorBrush(Colors.Black);
    spriteShape.CenterPoint = new Vector2(_imageSize.X / 2, _imageSize.Y / 2);

    ShapeVisual spriteShapeVisual = _compositor.CreateShapeVisual();
    spriteShapeVisual.BorderMode = CompositionBorderMode.Soft;
    spriteShapeVisual.Size = _imageSize;
    spriteShapeVisual.Shapes.Add(spriteShape);

    CompositionVisualSurface surface = _compositor.CreateVisualSurface();
    surface.SourceSize = _imageSize;
    surface.SourceVisual = spriteShapeVisual;

    CompositionMaskBrush maskBrush = _compositor.CreateMaskBrush();
    maskBrush.Source = imageSourceBrush;
    maskBrush.Mask = _compositor.CreateSurfaceBrush(surface);

    targetVisual.Brush = maskBrush;
}

EDITAR: También se puede obtener una máscara de una Forma, pero solo si ya está en el árbol visual:

Windows.UI.Xaml.Shapes.Shape rect = new Rectangle();
CompositionBrush mask = rect.GetAlphaMask();
NicoZhu-MSFT Nov 19 2020 at 12:45

API de composición de UWP: ¿Esquinas redondeadas?

Para su requerimiento, puede usar el SetElementChildVisualmétodo para agregar el CompositionRoundedRectangleGeometrya la página actual.

Por ejemplo:

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    var visual = ElementCompositionPreview.GetElementVisual(this);
    var compositor = visual.Compositor;
  
    CompositionRoundedRectangleGeometry roundedRectangle = compositor.CreateRoundedRectangleGeometry();
    roundedRectangle.Size = new Vector2(200, 200);
    roundedRectangle.CornerRadius = new Vector2(30,30);

    CompositionSpriteShape spriteShape = compositor.CreateSpriteShape(roundedRectangle);
    spriteShape.FillBrush = compositor.CreateColorBrush(Colors.Blue);
    spriteShape.CenterPoint = new Vector2(100, 100);

    ShapeVisual spriteShapeVisual = compositor.CreateShapeVisual();
    spriteShapeVisual.Size = new Vector2(200, 200); 
    
    spriteShapeVisual.Shapes.Clear();
    spriteShapeVisual.Shapes.Add(spriteShape);
  
    ElementCompositionPreview.SetElementChildVisual(this, spriteShapeVisual);
}