Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Tudo o que está visível no ecrã numa aplicação do WinUI é visível porque foi pintado com um pincel. Os pincéis permitem-lhe pintar objetos da interface de utilizador (UI) com conteúdos que vão desde cores sólidas simples até imagens, desenhos e cadeias de efeitos complexas. Este tópico introduz os conceitos de pintura com CompositionBrush.
Ao trabalhar com uma aplicação WinUI XAML, pode escolher pintar um UIElement com um pincel XAML ou um CompositionBrush. Normalmente, é mais fácil escolher um pincel XAML se o teu cenário já for suportado por um. Por exemplo, animar a cor de um botão ou alterar o preenchimento de texto ou de uma forma com uma imagem. Se precisar de algo que não seja suportado por um pincel XAML, como uma máscara animada, um estiramento animado de nove grelhas ou uma cadeia de efeitos, pode usar um CompositionBrush para pintar um UIElement através do XamlCompositionBrushBase.
Ao trabalhar com a camada Visual, é necessário usar um CompositionBrush para pintar a área de um SpriteVisual.
- Prerequisites
-
Pintar com CompositionBrush
- Pinta com uma cor sólida
- Pintar com um gradiente linear
- Pintura com gradiente radial
- Pintar com uma imagem
- Pinte com um desenho personalizado
- Pintar com um vídeo
- Pintar com efeito de filtro
- Pintar com um Pincel de Composição usando uma máscara de opacidade
- Pinte com um Pincel de Composição usando NineGrid stretch
- Pintar usando Pixels de Fundo
- Combinação de Composição Pincéis
- Usar um Pincel XAML versus CompositionBrush
- Tópicos Relacionados
Pré-requisitos
Esta visão geral assume que está familiarizado com a estrutura de uma aplicação básica de Composição, conforme descrito na visão geral da camada Visual.
Pintar com um Pincel de Composição
Um CompositionBrush "pinta" uma área com a sua saída. Diferentes escovas têm diferentes tipos de saída. Alguns pincéis pintam uma área com uma cor sólida, outros com um gradiente, imagem, desenho personalizado ou efeito. Existem também pincéis especializados que modificam o comportamento de outros pincéis. Por exemplo, uma máscara de opacidade pode controlar qual área é pintada por um CompositionBrush, ou uma grelha de nove partes pode controlar o estiramento aplicado a um CompositionBrush ao pintar uma área. CompositionBrush pode ser de um dos seguintes tipos:
| Classe | Detalhes |
|---|---|
| CompositionColorBrush | Pinta uma área com uma cor sólida |
| CompositionSurfaceBrush | Pinta uma área com o conteúdo de um ICompositionSurface |
| CompositionEffectBrush | Pinta uma área com o conteúdo de um efeito de composição |
| CompositionMaskBrush | Pinta um elemento visual com um CompositionBrush utilizando uma máscara de opacidade |
| ComposiçãoPincelNoveQuadrados | Pinta uma área com um CompositionBrush usando um NineGrid stretch |
| ComposiçãoGradienteLinear Brush | Pinta uma área com um gradiente linear |
| CompositionRadialGradientBrush | Pinta uma área com um gradiente radial |
| CompositionBackdropBrush | Pinta uma área amostrando pixels de fundo da aplicação ou diretamente atrás da janela da aplicação no ambiente de trabalho. Usado como entrada para outro CompositionBrush, como um CompositionEffectBrush |
Pinta com uma cor sólida
A CompositionColorBrush pinta uma área com uma cor sólida. Existem várias formas de especificar a cor de um SolidColorBrush. Por exemplo, pode especificar os seus canais alfa, vermelho, azul e verde (ARGB) ou usar uma das cores pré-definidas fornecidas pela classe Cores .
A ilustração e o código seguintes mostram uma pequena árvore visual para criar um retângulo que é traçado com um pincel de cor preta e pintado com um pincel de cor sólida que tem o valor de cor 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 com um gradiente linear
Um CompositionLinearGradientBrush pinta uma área com um gradiente linear. Um gradiente linear mistura duas ou mais cores ao longo de uma linha, o eixo do gradiente. Usas objetos GradientStop para especificar as cores no gradiente e as suas posições.
A ilustração e o código seguintes mostram um SpriteVisual pintado com um LinearGradientBrush com 2 stops, usando as cores vermelha e amarela.
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);
Pintura com gradiente radial
CompositionRadialGradientBrush pinta uma área com um gradiente radial. Um gradiente radial mistura duas ou mais cores, com o gradiente começando no centro da elipse e terminando no raio da elipse. Os objetos GradientStop são usados para definir as cores e a sua localização no gradiente.
A ilustração e o código seguintes mostram um SpriteVisual pintado com um RadialGradientBrush com 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 com uma imagem
CompositionSurfaceBrush pinta uma área com píxeis que são renderizados numa ICompositionSurface. Por exemplo, um CompositionSurfaceBrush pode ser usado para pintar uma área com uma imagem renderizada numa ICompositionSurface usando a API LoadedImageSurface .
A ilustração e o código seguintes mostram um SpriteVisual pintado com um bitmap de um alcaçuz renderizado numa ICompositionSurface usando LoadedImageSurface. As propriedades do CompositionSurfaceBrush podem ser usadas para esticar e alinhar o bitmap dentro dos limites do 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);
Pinte com um desenho personalizado
Um CompositionSurfaceBrush também pode ser usado para pintar uma área com pixels de um ICompositionSurface renderizado usando Win2D (ou D2D).
O código seguinte mostra um SpriteVisual pintado com uma sequência de texto renderizada numa ICompositionSurface usando Win2D. Para usar Win2D com WinUI, instale o pacote NuGet Microsoft.Graphics.Win2D no seu projeto.
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);
De forma semelhante, o CompositionSurfaceBrush também pode ser utilizado para renderizar um SpriteVisual com uma cadeia de troca utilizando interoperabilidade Win2D. Este exemplo fornece um exemplo de como usar o Win2D para pintar um SpriteVisual com uma swapchain.
Pintar com um vídeo
Um CompositionSurfaceBrush também pode ser utilizado para pintar uma área com píxeis provenientes de um ICompositionSurface renderizado através de um vídeo carregado pela classe MediaPlayer.
O código seguinte mostra um SpriteVisual pintado com um vídeo carregado num 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 com efeito de filtro
Um CompositionEffectBrush pinta uma área com a saída do CompositionEffect. Os efeitos na Camada Visual podem ser vistos como efeitos de filtro animáveis aplicados a uma coleção de conteúdos de fonte, como cores, gradientes, imagens, vídeos, swapchains, regiões da sua interface ou árvores de elementos visuais. O conteúdo de origem é normalmente especificado usando outro CompositionBrush.
A ilustração e o código a seguir mostram um SpriteVisual pintado com uma imagem de um gato, onde foi aplicado um efeito de filtro de desaturação.
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 mais informações sobre como criar um Efeito usando CompositionBrushes, veja Efeitos na camada Visual
Pintar com um CompositionBrush com máscara de opacidade aplicada
Um CompositionMaskBrush pinta uma área com um CompositionBrush que possui uma máscara de opacidade aplicada. A fonte da máscara de opacidade pode ser qualquer Pincel de Composição do tipo PincelCor de Composição, PincelGradienteLinear de Composição, PincelSuperfície de Composição, PincelEfeito de Composição ou PincelNoveGrelha de Composição. A máscara de opacidade deve ser especificada como um CompositionSurfaceBrush.
A ilustração e o código seguintes mostram um SpriteVisual pintado com um CompositionMaskBrush. A fonte da máscara é um CompositionLinearGradientBrush, que é mascarado para parecer um círculo utilizando uma imagem 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);
Pinte com um Pincel de ComposiçãoUsando o NineGrid stretch
A CompositionNineGridBrush pinta uma área com um CompositionBrush que é esticada usando a metáfora das nove grelhas. A metáfora das nove grelhas permite-lhe esticar as bordas e cantos de um CompositionBrush de forma diferente do seu centro. A fonte do esticar de nove grelhas pode ser qualquer CompositionBrush do tipo CompositionColorBrush, CompositionSurfaceBrush ou CompositionEffectBrush.
O código seguinte mostra um SpriteVisual pintado com um CompositionNineGridBrush. A fonte da máscara é um CompositionSurfaceBrush que é expandido através de uma grade de nove partes.
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 usando Píxeis de Fundo
Um pincel de fundo de composição pinta uma área com o conteúdo por trás da área. Um CompositionBackdropBrush nunca é usado isoladamente, mas sim usado como entrada para outro CompositionBrush, como um EffectBrush. Por exemplo, ao usar um CompositionBackdropBrush como entrada para um efeito de Desfoque, pode obter um efeito de vidro fosco.
O código seguinte mostra uma pequena árvore visual para criar uma imagem usando CompositionSurfaceBrush e uma sobreposição de vidro fosco acima da imagem. A sobreposição de vidro fosco é criada colocando um SpriteVisual preenchido com um EffectBrush acima da imagem. O EffectBrush usa um CompositionBackdropBrush como entrada para o efeito de desfoque.
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);
Combinação de Composição Pincéis
Vários CompositionBrushes utilizam outros CompositionBrushes como entradas. Por exemplo, o método SetSourceParameter pode ser usado para definir outro CompositionBrush como entrada para um CompositionEffectBrush. A tabela abaixo descreve as combinações suportadas de CompositionBrushes. Note que usar uma combinação não suportada lançará uma exceção.
| Escova | EffectBrush.SetSourceParameter() | MaskBrush.Mask | MaskBrush.Source | NineGridBrush.Source |
|---|---|---|---|---|
| ComposiçãoPincel de Cor | SIM | SIM | SIM | SIM |
| ComposiçãoLinear GradientBrush |
SIM | SIM | SIM | Não |
| CompositionSurfaceBrush | SIM | SIM | SIM | SIM |
| Pincel de Efeito de Composição | Não | Não | SIM | Não |
| ComposiçãoMáscaraPincel | Não | Não | Não | Não |
| ComposiçãoNovePincel da Grelha | SIM | SIM | SIM | Não |
| OrnamentaçãoBackdropBrush | SIM | Não | Não | Não |
Usar um Pincel XAML vs. Pincel de Composição
A tabela abaixo apresenta uma lista de cenários e se o uso de pincel XAML ou pincel de Composição é prescrito para pintar um UIElement ou um SpriteVisual na sua aplicação.
Observação
Se for sugerido um CompositionBrush para um UIElement XAML, assume-se que o CompositionBrush está embalado utilizando uma XamlCompositionBrushBase.
| Scenario | XAML UIElement | Composição SpriteVisual |
|---|---|---|
| Pinte uma área com cor sólida | SolidColorBrush | ComposiçãoPincel de Cor |
| Pinta uma área com cor animada | SolidColorBrush | CompositionColorBrush |
| Pinte uma área com um gradiente estático | LinearGradientBrush | ComposiçãoGradienteLinear Brush |
| Pinta uma área com paradas de gradiente animadas | ComposiçãoGradienteLinear Brush | ComposiçãoGradienteLinear Brush |
| Pinte uma área com uma imagem | ImageBrush | CompositionSurfaceBrush |
| Pinte uma área com uma página web | WebView2 | N/A |
| Pinte uma área com uma imagem usando o NineGrid stretch | Controlo de Imagem | Composição da Grade de Nove Pincéis |
| Pinta uma área com alongamento animado do NineGrid | Pincel-de-Composição-nove-da-grelha | ComposiçãoPincelNoveQuadrados |
| Pinte uma área com um swapchain | SwapChainPanel | CompositionSurfaceBrush com interoperabilidade de swapchain |
| Pinta uma área com um vídeo | MediaPlayerElement | CompositionSurfaceBrush com interoperação de média |
| Pinte uma área com desenhos 2D personalizados | CanvasControl do Win2D | CompositionSurfaceBrush com interoperabilidade com Win2D |
| Pinta uma área com máscara não animada | Utilize formas XAML para definir uma máscara | CompositionMaskBrush |
| Pinta uma área com uma máscara animada | CompositionMaskBrush | CompositionMaskBrush |
| Pinte uma área com um efeito de filtro animado | CompositionEffectBrush | CompositionEffectBrush |
| Pinte uma área com um efeito aplicado aos píxeis do fundo | CompositionBackdropBrush | CompositionBackdropBrush |
Tópicos relacionados
Interoperação nativa DirectX e Direct2D com BeginDraw e EndDraw
Interoperabilidade de pincéis XAML com XamlCompositionBrushBase
Windows developer