Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Todo lo que está visible en la pantalla en una aplicación WinUI es visible porque fue pintado por un pincel. Los pinceles permiten pintar objetos de interfaz de usuario (UI) con contenido que va desde colores sólidos simples hasta imágenes, dibujos y cadenas de efectos complejas. En este tema se presentan los conceptos de pintura con CompositionBrush.
Al trabajar con una aplicación XAML de WinUI, puedes elegir pintar un UIElement con un pincel XAML o compositionBrush. Normalmente, es más fácil elegir un pincel XAML si el escenario ya es compatible con uno. Por ejemplo, animar el color de un botón o cambiar el relleno de texto o una forma con una imagen. Si necesitas algo que no sea compatible con un pincel XAML, como una máscara animada, una extensión animada de nueve cuadrículas o una cadena de efectos, puedes usar compositionBrush para pintar un UIElement a través de XamlCompositionBrushBase.
Al trabajar con la capa visual, se debe usar compositionBrush para pintar el área de un SpriteVisual.
- Requisitos previos
-
Pintar con CompositionBrush
- Pintar con un color sólido
- Pintar con un degradado lineal
- Pintar con un degradado radial
- Pintar con una imagen
- Pintar utilizando un diseño personalizado
- Pintar con un video
- Pintar con un efecto de filtro
- Pinta con un CompositionBrush utilizando una máscara de opacidad
- Pintar con un compositionBrush mediante nineGrid stretch
- Pintar utilizando píxeles de fondo
- Combinando pinceles de composición
- Usar un pincel XAML frente a CompositionBrush
- Temas relacionados
Prerrequisitos
En esta visión general se da por supuesto que está familiarizado con la estructura de una aplicación de composición básica, como se describe en la información general de la capa Visual.
Pintar con un pincel de composición
Un CompositionBrush "pinta" un área con su salida. Los pinceles diferentes tienen diferentes tipos de salida. Algunos pinceles pintan un área con un color sólido, otros con un degradado, una imagen, un dibujo personalizado o un efecto. También hay pinceles especializados que modifican el comportamiento de otros pinceles. Por ejemplo, la máscara de opacidad se puede usar para controlar qué área está pintada por un CompositionBrush, o se puede usar una cuadrícula de nueve para controlar la extensión aplicada a un CompositionBrush al pintar un área. CompositionBrush puede ser de uno de los siguientes tipos:
| Class | Detalles |
|---|---|
| CompositionColorBrush | Pinta un área con un color sólido |
| CompositionSurfaceBrush | Dibuja un área utilizando el contenido de un ICompositionSurface |
| CompositionEffectBrush | Pinta un área con el contenido de un efecto de composición |
| CompositionMaskBrush | Pinta un objeto visual con un CompositionBrush y una máscara de opacidad |
| CompositionNineGridBrush | Pinta un área con un CompositionBrush usando un estiramiento de NineGrid |
| CompositionLinearGradientBrush | Pinta un área con un degradado lineal |
| CompositionRadialGradientBrush | Pinta un área con un degradado radial |
| CompositionBackdropBrush | Pinta un área mediante el muestreo de píxeles de fondo de la aplicación o píxeles directamente detrás de la ventana de la aplicación en el escritorio. Se usa como entrada para otro CompositionBrush como el CompositionEffectBrush |
Pintar con un color sólido
Un CompositionColorBrush pinta un área con un color sólido. Hay una variedad de maneras de especificar el color de un SolidColorBrush. Por ejemplo, puede especificar sus canales alfa, rojo, azul y verde (ARGB) o usar uno de los colores predefinidos proporcionados por la clase Colors .
En la siguiente ilustración y código se muestra un pequeño árbol visual para crear un rectángulo que se trazó con un pincel de color negro y se pinta con un pincel de color sólido que tiene el valor de color de 0x9ACD32.
Compositor _compositor;
ContainerVisual _container;
SpriteVisual _colorVisual1, _colorVisual2;
CompositionColorBrush _blackBrush, _greenBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_container = _compositor.CreateContainerVisual();
_blackBrush = _compositor.CreateColorBrush(Colors.Black);
_colorVisual1 = _compositor.CreateSpriteVisual();
_colorVisual1.Brush = _blackBrush;
_colorVisual1.Size = new Vector2(156, 156);
_colorVisual1.Offset = new Vector3(0, 0, 0);
_container.Children.InsertAtBottom(_colorVisual1);
_greenBrush = _compositor.CreateColorBrush(Color.FromArgb(0xff, 0x9A, 0xCD, 0x32));
_colorVisual2 = _compositor.CreateSpriteVisual();
_colorVisual2.Brush = _greenBrush;
_colorVisual2.Size = new Vector2(150, 150);
_colorVisual2.Offset = new Vector3(3, 3, 0);
_container.Children.InsertAtBottom(_colorVisual2);
Pintar con un degradado lineal
CompositionLinearGradientBrush pinta un área con un degradado lineal. Un degradado lineal combina dos o más colores a través de una línea, el eje de degradado. Los objetos GradientStop se usan para especificar los colores en el degradado y sus posiciones.
En la siguiente ilustración y código se muestra un SpriteVisual pintado con LinearGradientBrush con 2 puntos utilizando colores rojo y amarillo.
Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionLinearGradientBrush _redyellowBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_redyellowBrush = _compositor.CreateLinearGradientBrush();
_redyellowBrush.ColorStops.Add(_compositor.CreateColorGradientStop(0, Colors.Red));
_redyellowBrush.ColorStops.Add(_compositor.CreateColorGradientStop(1, Colors.Yellow));
_gradientVisual = _compositor.CreateSpriteVisual();
_gradientVisual.Brush = _redyellowBrush;
_gradientVisual.Size = new Vector2(156, 156);
Pintar con un degradado radial
Un CompositionRadialGradientBrush pinta un área con un degradado radial. Un degradado radial combina dos o más colores con el degradado comenzando desde el centro de la elipse y finalizando en el radio de la elipse. Los objetos GradientStop se usan para definir los colores y su ubicación en el degradado.
En la siguiente ilustración y código se muestra un SpriteVisual pintado con un RadialGradientBrush con 2 GradientStops.
Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionRadialGradientBrush RGBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
RGBrush = _compositor.CreateRadialGradientBrush();
RGBrush.ColorStops.Add(_compositor.CreateColorGradientStop(0, Colors.Aquamarine));
RGBrush.ColorStops.Add(_compositor.CreateColorGradientStop(1, Colors.DeepPink));
_gradientVisual = _compositor.CreateSpriteVisual();
_gradientVisual.Brush = RGBrush;
_gradientVisual.Size = new Vector2(200, 200);
Pintar con una imagen
Un CompositionSurfaceBrush pinta un área con píxeles representados en un ICompositionSurface. Por ejemplo, se puede usar CompositionSurfaceBrush para pintar un área con una imagen que se ha renderizado en un ICompositionSurface mediante la API LoadedImageSurface.
En la siguiente ilustración y código se muestra un SpriteVisual pintado con un bitmap de un regaliz representado en un ICompositionSurface mediante LoadedImageSurface. Las propiedades de CompositionSurfaceBrush se pueden usar para estirar y alinear el mapa de bits dentro de los límites del visual.
Compositor _compositor;
SpriteVisual _imageVisual;
CompositionSurfaceBrush _imageBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_imageBrush = _compositor.CreateSurfaceBrush();
// The loadedSurface has a size of 0x0 till the image has been downloaded, decoded and loaded to the surface. We can assign the surface to the CompositionSurfaceBrush and it will show up once the image is loaded to the surface.
LoadedImageSurface _loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/licorice.jpg"));
_imageBrush.Surface = _loadedSurface;
_imageVisual = _compositor.CreateSpriteVisual();
_imageVisual.Brush = _imageBrush;
_imageVisual.Size = new Vector2(156, 156);
Pintar con un dibujo personalizado
Un CompositionSurfaceBrush también se puede usar para pintar un área con píxeles de un ICompositionSurface representado mediante Win2D (o D2D).
En el código siguiente se muestra un SpriteVisual pintado con un fragmento de texto procesado en una ICompositionSurface mediante Win2D. Para usar Win2D con WinUI, instale el paquete NuGet Microsoft.Graphics.Win2D en el proyecto.
Compositor _compositor;
CanvasDevice _device;
CompositionGraphicsDevice _compositionGraphicsDevice;
SpriteVisual _drawingVisual;
CompositionSurfaceBrush _drawingBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_device = CanvasDevice.GetSharedDevice();
_compositionGraphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(_compositor, _device);
_drawingBrush = _compositor.CreateSurfaceBrush();
CompositionDrawingSurface _drawingSurface = _compositionGraphicsDevice.CreateDrawingSurface(
new Size(256, 256),
DirectXPixelFormat.B8G8R8A8UIntNormalized,
DirectXAlphaMode.Premultiplied);
using (var ds = CanvasComposition.CreateDrawingSession(_drawingSurface))
{
ds.Clear(Colors.Transparent);
var rect = new Rect(new Point(2, 2), (_drawingSurface.Size.ToVector2() - new Vector2(4, 4)).ToSize());
ds.FillRoundedRectangle(rect, 15, 15, Colors.LightBlue);
ds.DrawRoundedRectangle(rect, 15, 15, Colors.Gray, 2);
ds.DrawText("This is a composition drawing surface", rect, Colors.Black, new CanvasTextFormat()
{
FontFamily = "Comic Sans MS",
FontSize = 32,
WordWrapping = CanvasWordWrapping.WholeWord,
VerticalAlignment = CanvasVerticalAlignment.Center,
HorizontalAlignment = CanvasHorizontalAlignment.Center
});
}
_drawingBrush.Surface = _drawingSurface;
_drawingVisual = _compositor.CreateSpriteVisual();
_drawingVisual.Brush = _drawingBrush;
_drawingVisual.Size = new Vector2(156, 156);
Del mismo modo, CompositionSurfaceBrush también se puede usar para pintar un SpriteVisual con un SwapChain utilizando la interoperabilidad de Win2D. Este ejemplo muestra cómo usar Win2D para pintar un SpriteVisual con un swapchain.
Pintar con un vídeo
También se puede usar compositionSurfaceBrush para pintar un área con píxeles de un ICompositionSurface representado mediante un vídeo cargado a través de la clase MediaPlayer .
En el código siguiente se muestra un SpriteVisual pintado con un vídeo cargado en un ICompositionSurface.
Compositor _compositor;
SpriteVisual _videoVisual;
CompositionSurfaceBrush _videoBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
// MediaPlayer setup with a source URI.
_mediaPlayer = new MediaPlayer();
// Get a source from a URI. This could also come from a file or a stream.
var source = MediaSource.CreateFromUri(new Uri("https://go.microsoft.com/fwlink/?LinkID=809007&clcid=0x409"));
var item = new MediaPlaybackItem(source);
_mediaPlayer.Source = item;
_mediaPlayer.IsLoopingEnabled = true;
// Get the surface from MediaPlayer and put it on a brush.
_videoSurface = _mediaPlayer.GetSurface(_compositor);
_videoBrush = _compositor.CreateSurfaceBrush(_videoSurface.CompositionSurface);
_videoVisual = _compositor.CreateSpriteVisual();
_videoVisual.Brush = _videoBrush;
_videoVisual.Size = new Vector2(156, 156);
Pintar con un efecto de filtro
Un CompositionEffectBrush pinta un área usando el resultado de un CompositionEffect. Los efectos de la capa visual pueden considerarse como efectos de filtro animables aplicados a una colección de contenido de origen, como colores, degradados, imágenes, vídeos, cadenas de intercambio, regiones de la interfaz de usuario o árboles de objetos visuales. El contenido de origen se especifica normalmente mediante otro CompositionBrush.
En la siguiente ilustración y código se muestra un SpriteVisual representado con una imagen de un gato, a la que se ha aplicado un filtro de desaturación.
Compositor _compositor;
SpriteVisual _effectVisual;
CompositionEffectBrush _effectBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
var graphicsEffect = new SaturationEffect
{
Saturation = 0.0f,
Source = new CompositionEffectSourceParameter("mySource")
};
var effectFactory = _compositor.CreateEffectFactory(graphicsEffect);
_effectBrush = effectFactory.CreateBrush();
CompositionSurfaceBrush surfaceBrush = _compositor.CreateSurfaceBrush();
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/cat.jpg"));
surfaceBrush.Surface = loadedSurface;
_effectBrush.SetSourceParameter("mySource", surfaceBrush);
_effectVisual = _compositor.CreateSpriteVisual();
_effectVisual.Brush = _effectBrush;
_effectVisual.Size = new Vector2(156, 156);
Para obtener más información sobre cómo crear un efecto mediante CompositionBrushes, vea Efectos en la capa visual.
Pinte con un pincel de composición al que se le haya aplicado una máscara de opacidad
Un CompositionMaskBrush pinta un área con un CompositionBrush con una máscara de opacidad aplicada. La fuente de la máscara de opacidad puede ser cualquier CompositionBrush, ya sea de tipo CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush o CompositionNineGridBrush. La máscara de opacidad debe especificarse como compositionSurfaceBrush.
En la siguiente ilustración y código se muestra un SpriteVisual pintado con un CompositionMaskBrush. El origen de la máscara es un compositionLinearGradientBrush que se enmascara para parecerse a un círculo con una imagen de círculo como máscara.
Compositor _compositor;
SpriteVisual _maskVisual;
CompositionMaskBrush _maskBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_maskBrush = _compositor.CreateMaskBrush();
CompositionLinearGradientBrush _sourceGradient = _compositor.CreateLinearGradientBrush();
_sourceGradient.ColorStops.Add(_compositor.CreateColorGradientStop(0,Colors.Red));
_sourceGradient.ColorStops.Add(_compositor.CreateColorGradientStop(1,Colors.Yellow));
_maskBrush.Source = _sourceGradient;
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/circle.png"), new Size(156.0, 156.0));
_maskBrush.Mask = _compositor.CreateSurfaceBrush(loadedSurface);
_maskVisual = _compositor.CreateSpriteVisual();
_maskVisual.Brush = _maskBrush;
_maskVisual.Size = new Vector2(156, 156);
Pintar con un CompositionBrush usando NineGrid stretch
Un CompositionNineGridBrush pinta un área con un CompositionBrush que se extiende utilizando la metáfora de nueve cuadrículas. La metáfora de nueve cuadrículas te permite estirar bordes y esquinas de un CompositionBrush de forma diferente a su centro. La fuente de la extensión de nueve cuadrículas puede ser cualquier CompositionBrush de tipo CompositionColorBrush, CompositionSurfaceBrush o CompositionEffectBrush.
En el código siguiente se muestra un SpriteVisual pintado con CompositionNineGridBrush. La fuente de la máscara es un CompositionSurfaceBrush que se extiende mediante una cuadrícula de Nueve.
Compositor _compositor;
SpriteVisual _nineGridVisual;
CompositionNineGridBrush _nineGridBrush;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
_nineGridBrush = _compositor.CreateNineGridBrush();
// nineGridImage.png is 50x50 pixels; nine-grid insets, as measured relative to the actual size of the image, are: left = 1, top = 5, right = 10, bottom = 20 (in pixels)
LoadedImageSurface _imageSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/nineGridImage.png"));
CompositionSurfaceBrush sourceBrush = _compositor.CreateSurfaceBrush(_imageSurface);
_nineGridBrush.Source = sourceBrush;
// Set nine-grid insets.
_nineGridBrush.SetInsets(1, 5, 10, 20);
// Set the appropriate stretch on the SurfaceBrush for the center of the nine-grid.
sourceBrush.Stretch = CompositionStretch.Fill;
_nineGridVisual = _compositor.CreateSpriteVisual();
_nineGridVisual.Brush = _nineGridBrush;
_nineGridVisual.Size = new Vector2(100, 75);
Pintar con píxeles de fondo
Un CompositionBackdropBrush pinta un área con el contenido que está detrás de ella. Un CompositionBackdropBrush nunca se usa por sí mismo, sino que se usa como entrada para otro CompositionBrush como EffectBrush. Por ejemplo, mediante el uso de CompositionBackdropBrush como entrada para un efecto de desenfoque, puede lograr un efecto de vidrio esmerilado.
En el siguiente código se muestra un pequeño árbol visual para crear una imagen usando CompositionSurfaceBrush y una capa de vidrio esmerilado sobre la imagen. La superposición de vidrio esmerilado se crea colocando un SpriteVisual que utiliza un EffectBrush sobre la imagen. EffectBrush usa CompositionBackdropBrush como entrada para el efecto de desenfoque.
Compositor _compositor;
ContainerVisual _containerVisual;
SpriteVisual _imageVisual;
SpriteVisual _backdropVisual;
_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;
// Create a container visual to host the visual tree.
_containerVisual = _compositor.CreateContainerVisual();
// Create _imageVisual and add it to the bottom of the container visual.
CompositionSurfaceBrush _licoriceBrush = _compositor.CreateSurfaceBrush();
LoadedImageSurface loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/licorice.jpg"));
_licoriceBrush.Surface = loadedSurface;
_imageVisual = _compositor.CreateSpriteVisual();
_imageVisual.Brush = _licoriceBrush;
_imageVisual.Size = new Vector2(156, 156);
_imageVisual.Offset = new Vector3(0, 0, 0);
_containerVisual.Children.InsertAtBottom(_imageVisual);
// Create a SpriteVisual and add it to the top of the container visual.
// Paint the visual with an EffectBrush that applies blur to the content underneath it.
GaussianBlurEffect blurEffect = new GaussianBlurEffect()
{
Name = "Blur",
BlurAmount = 1.0f,
BorderMode = EffectBorderMode.Hard,
Source = new CompositionEffectSourceParameter("source")
};
CompositionEffectFactory blurEffectFactory = _compositor.CreateEffectFactory(blurEffect);
CompositionEffectBrush _backdropBrush = blurEffectFactory.CreateBrush();
// Create a BackdropBrush and bind it to the EffectSourceParameter source.
_backdropBrush.SetSourceParameter("source", _compositor.CreateBackdropBrush());
_backdropVisual = _compositor.CreateSpriteVisual();
_backdropVisual.Brush = _backdropBrush;
_backdropVisual.Size = new Vector2(78, 78);
_backdropVisual.Offset = new Vector3(39, 39, 0);
_containerVisual.Children.InsertAtTop(_backdropVisual);
Combinar CompositionBrushes
Una serie de CompositionBrushes usa otros CompositionBrushes como entradas. Por ejemplo, el método SetSourceParameter se puede utilizar para establecer otro CompositionBrush como entrada para un CompositionEffectBrush. En la tabla siguiente se describen las combinaciones admitidas de CompositionBrushes. Tenga en cuenta que el uso de una combinación no admitida producirá una excepción.
| Pincel | EffectBrush.SetSourceParameter() | PincelDeMáscara.Máscara | MaskBrush.Source | NineGridBrush.Source |
|---|---|---|---|---|
| CompositionColorBrush | SÍ | SÍ | SÍ | SÍ |
| CompositionLinear GradientBrush |
SÍ | SÍ | SÍ | NO |
| CompositionSurfaceBrush | SÍ | SÍ | SÍ | SÍ |
| CompositionEffectBrush | NO | NO | SÍ | NO |
| PincelDeMáscaraDeComposición | NO | NO | NO | NO |
| CompositionNineGridBrush | SÍ | SÍ | SÍ | NO |
| CompositionBackdropBrush | SÍ | NO | NO | NO |
Usar un pincel XAML versus un CompositionBrush
En la siguiente tabla se muestra una lista de escenarios y se indica el uso prescrito de un pincel XAML o Composition al aplicar pintura a un UIElement o un SpriteVisual en su aplicación.
Nota:
Si se sugiere un CompositionBrush para un UIElement XAML, se supone que el CompositionBrush se empaqueta mediante XamlCompositionBrushBase.
| Escenario | XAML UIElement | SpriteVisual de composición |
|---|---|---|
| Pintar un área con color sólido | SolidColorBrush | CompositionColorBrush |
| Pintar un área con color animado | SolidColorBrush | CompositionColorBrush |
| Pintar un área con un degradado estático | LinearGradientBrush | CompositionLinearGradientBrush |
| Pintar un área con paradas de degradado animadas | CompositionLinearGradientBrush | CompositionLinearGradientBrush |
| Pintar un área con una imagen | ImageBrush | CompositionSurfaceBrush |
| Pintar un área con una página web | WebView2 | N/A |
| Pintar un área con una imagen mediante el stretch de NineGrid | Image Control | CompositionNineGridBrush |
| Pintar un área con la animación de NineGrid stretch | CompositionNineGridBrush | CompositionNineGridBrush |
| Pintar un área con una cadena de intercambio | SwapChainPanel | Interoperabilidad de swapchain con CompositionSurfaceBrush |
| Pintar un área con un vídeo | MediaPlayerElement | CompositionSurfaceBrush con interoperabilidad multimedia |
| Pintar un área con dibujo 2D personalizado | CanvasControl desde Win2D | Interoperabilidad de CompositionSurfaceBrush con Win2D |
| Pintar un área usando una máscara que no esté animada | Utilice figuras XAML para definir una máscara | CompositionMaskBrush |
| Pintar un área con una máscara animada | CompositionMaskBrush | CompositionMaskBrush |
| Pintar un área con un efecto de filtro animado | CompositionEffectBrush | CompositionEffectBrush |
| Pintar un área aplicando un efecto a los píxeles de fondo | CompositionBackdropBrush | CompositionBackdropBrush |
Temas relacionados
Interoperabilidad nativa de la composición entre DirectX y Direct2D con BeginDraw y EndDraw
Interoperabilidad de brochas XAML con XamlCompositionBrushBase