Share via


Pincéis de composição

Todos os itens na tela de um aplicativo UWP são visíveis devido à pintura com um Pincel. Pincéis permitem pintar objetos de interface de usuário com conteúdo que varia de cores simples e sólidas para imagens ou desenhos até uma cadeia de efeitos complexos. Este tópico apresenta os conceitos de pintura com CompositionBrush.

Observe que, ao trabalhar com o aplicativo UWP XAML, você pode optar por pintar um UIElement com um Pincel XAML ou um CompositionBrush. Normalmente, é aconselhável e mais fácil escolher um pincel XAML se o cenário for compatível com um pincel XAML. Por exemplo, animar a cor de um botão, alterar o preenchimento de um texto ou uma forma com uma imagem. Por outro lado, se você estiver tentando fazer algo que não é compatível com um pincel XAML como pintura com uma máscara animada ou um alongamento animado de nove grades ou uma cadeia de efeitos, você pode usar um CompositionBrush para pintar um UIElement por meio do uso de XamlCompositionBrushBase.

Ao trabalhar com a amada Visual, é necessário usar um CompositionBrush para pintar a área de um SpriteVisual.

Pré-requisitos

Esta visão geral parte do princípio de que você já está familiarizado com a estrutura de um aplicativo básico de Composição, como descrito na Visão geral da camada visual.

Pintar com um CompositionBrush

Um CompositionBrush "pinta" uma área com sua saída. Pincéis diferentes têm tipos diferentes de saída. Alguns pincéis pintam uma área com uma cor sólida, outros com um gradiente, uma imagem, um desenho personalizado ou um efeito. Também há pincéis especializados que modificam o comportamento de outros pincéis. Por exemplo, a máscara de opacidade pode ser usada para controlar qual área é pintada por um CompositionBrush ou é possível usar nove grades para controlar a ampliação aplicada a um CompositionBrush ao pintar uma área. O CompositionBrush pode ser de um dos seguintes tipos:

Classe Detalhes Introduzido em
CompositionColorBrush Pinta uma área com uma cor sólida Windows 10, versão 1511 (SDK 10586)
CompositionSurfaceBrush Pinta uma área com o conteúdo de um ICompositionSurface Windows 10, versão 1511 (SDK 10586)
CompositionEffectBrush Pinta uma área com o conteúdo de um efeito de composição Windows 10, versão 1511 (SDK 10586)
CompositionMaskBrush Pinta um visual usando um CompositionBrush com uma máscara de opacidade Windows 10, versão 1607 (SDK 14393)
CompositionNineGridBrush Pinta uma área com uma CompositionBrush usando uma ampliação NineGrid Windows 10, versão 1607 (SDK 14393)
CompositionLinearGradientBrush Pinta uma área com um gradiente linear Windows 10, versão 1709 (SDK 16299)
CompositionRadialGradientBrush Pinta uma área com um gradiente radial Windows 10, versão 1903 (SDK do Insider Preview)
CompositionBackdropBrush Pinta uma área pela amostragem dos pixels de fundo de um aplicativo ou dos pixels diretamente por trás da janela do aplicativo na área de trabalho. Usado como uma entrada para outro CompositionBrush como um CompositionEffectBrush Windows 10, versão 1607 (SDK 14393)

Pintar com uma cor sólida

Um CompositionColorBrush pinta uma área com uma cor sólida. Existem diversas maneiras de especificar a cor de um SolidColorBrush. Por exemplo, você pode especificar os canais de alfa, vermelho, azul e verde (ARGB) ou usar uma das cores predefinidas fornecidas pela classe Cores.

A ilustração e o código a seguir mostram uma pequena árvore visual para criar um retângulo tracejado com um pincel de cor preta e pintado com um pincel de cor sólida que tem o valor de cor 0x9ACD32.

CompositionColorBrush

Compositor _compositor;
ContainerVisual _container;
SpriteVisual _colorVisual1, _colorVisual2;
CompositionColorBrush _blackBrush, _greenBrush;

_compositor = Window.Current.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 combina duas ou mais cores em uma linha, o eixo de gradiente. Você pode usar objetos GradientStop para especificar as cores no gradiente e suas posições.

A ilustração e o código a seguir mostram um SpriteVisual pintado com um LinearGradientBrush e duas paradas, usando uma cor de vermelha e amarela.

CompositionLinearGradientBrush

Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionLinearGradientBrush _redyellowBrush;

_compositor = Window.Current.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 com um gradiente radial

Um CompositionRadialGradientBrush pinta uma área com um gradiente radial. Um gradiente radial combina duas ou mais cores com o gradiente começando do centro da elipse e terminando no raio da elipse. Objetos GradientStop são usados para definir as cores e sua localização no gradiente.

A ilustração e o código a seguir mostram um SpriteVisual pintado com um RadialGradientBrush com 2 GradientStops.

CompositionRadialGradientBrush

Compositor _compositor;
SpriteVisual _gradientVisual;
CompositionRadialGradientBrush RGBrush;

_compositor = Window.Current.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

Um CompositionSurfaceBrush pinta uma área com pixels renderizados em um ICompositionSurface. Por exemplo, um CompositionSurfaceBrush pode ser usado para pintar uma área com uma imagem renderizada em uma superfície ICompositionSurface usando a API LoadedImageSurface.

A ilustração e o código a seguir mostram um SpriteVisual pintado com um bitmap de um licorice renderizado em um ICompositionSurface usando LoadedImageSurface. As propriedades do CompositionSurfaceBrush podem ser usadas para ampliar e alinhar o bitmap nos limites do elemento visual.

CompositionSurfaceBrush

Compositor _compositor;
SpriteVisual _imageVisual;
CompositionSurfaceBrush _imageBrush;

_compositor = Window.Current.Compositor;

_imageBrush = _compositor.CreateSurfaceBrush();

// The loadedSurface has a size of 0x0 till the image has been 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 com um desenho personalizado

A CompositionSurfaceBrush também pode ser usado para pintar uma área com pixels de um ICompositionSurface renderizado usando Win2D (ou D2D).

O código a seguir mostra um SpriteVisual pintado com uma execução de texto renderizada em um ICompositionSurface usando Win2D. Observe que para usar o Win2D, você deve incluir o pacote NuGet Win2D ao projeto.

Compositor _compositor;
CanvasDevice _device;
CompositionGraphicsDevice _compositionGraphicsDevice;
SpriteVisual _drawingVisual;
CompositionSurfaceBrush _drawingBrush;

_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);

Da mesma forma, o CompositionSurfaceBrush também pode ser usado para pintar um SpriteVisual com uma Cadeia de permuta usando a interoperabilidade do Win2D. Este exemplo mostra como usar o Win2D para pintar um SpriteVisual com uma cadeia de permuta.

Pintar com um vídeo

Um CompositionSurfaceBrush também pode ser usado para pintar uma área com pixels de um ICompositionSurface renderizado usando um vídeo carregado pela classe MediaPlayer.

O código a seguir mostra um SpriteVisual pintado com um vídeo carregado em um ICompositionSurface.

Compositor _compositor;
SpriteVisual _videoVisual;
CompositionSurfaceBrush _videoBrush;

// MediaPlayer set up with a create from URI

_mediaPlayer = new MediaPlayer();

// Get a source from a URI. This could also be from a file via a picker 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 um efeito de filtro

Um CompositionEffectBrush pinta uma área com a saída de um CompositionEffect. Efeitos na Camada visual podem ser pensados como efeitos de filtro animados aplicados a uma coleção de conteúdo de origem, como cores, gradientes, imagens, vídeos, cadeias de permuta, regiões da interface do usuário 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 com o efeito de filtro de dessaturação aplicado.

CompositionEffectBrush

Compositor _compositor;
SpriteVisual _effectVisual;
CompositionEffectBrush _effectBrush;

_compositor = Window.Current.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 obter mais informações sobre como criar um Efeito usando CompositionBrushes, consulte Efeitos na camada visual

Pintar usando um CompositionBrush com uma máscara de opacidade aplicada

O CompositionMaskBrush pinta uma área com um CompositionBrush usando uma máscara de opacidade aplicada a ele. A origem da máscara de opacidade pode ser qualquer CompositionBrush do tipo CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush ou CompositionNineGridBrush. A máscara de opacidade deve ser especificada como um CompositionSurfaceBrush.

A ilustração e o código a seguir mostram um SpriteVisual pintado com um CompositionMaskBrush. A origem da máscara é um CompositionLinearGradientBrush mascarado com a aparência de um círculo usando uma imagem do círculo como uma máscara.

CompositionMaskBrush

Compositor _compositor;
SpriteVisual _maskVisual;
CompositionMaskBrush _maskBrush;

_compositor = Window.Current.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 com um CompositionBrush usando a ampliação NineGrid

A CompositionNineGridBrush pinta uma área com um CompositionBrush, que é ampliado usando a metáfora de nove grades. A metáfora de nove grades permite que você amplie bordas e cantos de um CompositionBrush de modo diferente do seu centro. A origem da ampliação de nove grades pode ser qualquer CompositionBrush do tipo CompositionColorBrush, CompositionSurfaceBrush ou CompositionEffectBrush.

O código a seguir mostram um SpriteVisual pintado com um CompositionNineGridBrush. A origem da máscara é um CompositionSurfaceBrush ampliado usando as Nove grades.

Compositor _compositor;
SpriteVisual _nineGridVisual;
CompositionNineGridBrush _nineGridBrush;

_compositor = Window.Current.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"));
_nineGridBrush.Source = _compositor.CreateSurfaceBrush(_imageSurface);

// set Nine-Grid Insets

_ninegridBrush.SetInsets(1, 5, 10, 20);

// set appropriate Stretch on SurfaceBrush for Center of Nine-Grid

sourceBrush.Stretch = CompositionStretch.Fill;

_nineGridVisual = _compositor.CreateSpriteVisual();
_nineGridVisual.Brush = _ninegridBrush;
_nineGridVisual.Size = new Vector2(100, 75);

Pintar usando Pixels de fundo

Um CompositionBackdropBrush pinta uma área com o conteúdo por trás da área. Um CompositionBackdropBrush nunca é usado por conta própria, mas em vez disso, é usado como uma entrada para outro CompositionBrush como um EffectBrush. Por exemplo, ao usar um CompositionBackdropBrush como uma entrada para um efeito de Desfoque, você pode obter um efeito de vidro fosco.

O código a seguir mostra uma pequena árvore visual para criar uma imagem usando o CompositionSurfaceBrush e uma sobreposição de vidro fosco acima da imagem. A sobreposição de vidro fosco é criada ao colocar um SpriteVisual preenchido com um EffectBrush acima da imagem. O EffectBrush usa um CompositionBackdropBrush como uma entrada para o efeito de desfoque.

Compositor _compositor;
SpriteVisual _containerVisual;
SpriteVisual _imageVisual;
SpriteVisual _backdropVisual;

_compositor = Window.Current.Compositor;

// Create container visual to host the visual tree
_containerVisual = _compositor.CreateContainerVisual();

// Create _imageVisual and add it to the bottom of the container visual.
// Paint the visual with an image.

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 containerVisual.
// Paint the visual with an EffectBrush that applies blur to the content
// underneath the Visual to create a frosted glass effect.

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 = _licoriceBrush;
_backdropVisual.Size = new Vector2(78, 78);
_backdropVisual.Offset = new Vector3(39, 39, 0);
_containerVisual.Children.InsertAtTop(_backdropVisual);

Combinar CompositionBrushes

Alguns CompositionBrushes usam outros CompositionBrushes como entradas. Por exemplo, ao usar o método SetSourceParameter é possível definir outro CompositionBrush como uma entrada para um CompositionEffectBrush. A tabela abaixo descreve as combinações compatíveis de CompositionBrushes. Observe que o uso de uma combinação sem suporte gera uma exceção.

Pincel EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
CompositionColorBrush YES YES YES YES
CompositionLinear
GradientBrush
YES YES YES Não
CompositionSurfaceBrush YES YES YES YES
CompositionEffectBrush Não Não YES Não
CompositionMaskBrush Não Não Não Não
CompositionNineGridBrush YES YES YES Não
CompositionBackdropBrush YES Não Não Não

Usar um Pincel XAML em comparação ao CompositionBrush

A tabela a seguir fornece uma lista dos cenários e se o uso do pincel XAML ou de Composição é recomendado ao pintar um UIElement ou um SpriteVisual no aplicativo.

Observação

Se um CompositionBrush for sugerido para um UIElement XAML, considera-se que o CompositionBrush é empacotado usando um XamlCompositionBrushBase.

Cenário XAML UIElement SpriteVisual de composição
Pintar uma área com cores sólidas SolidColorBrush CompositionColorBrush
Pintar uma área com cores animadas SolidColorBrush CompositionColorBrush
Pintar uma área com um gradiente estático LinearGradientBrush CompositionLinearGradientBrush
Pintar uma área com paradas de gradiente animado CompositionLinearGradientBrush CompositionLinearGradientBrush
Pintar uma área com uma imagem ImageBrush CompositionSurfaceBrush
Pintar uma área com uma página da Web WebViewBrush N/D
Pintar uma área com uma imagem usando a ampliação NineGrid Controle de imagem CompositionNineGridBrush
Pintar uma área com uma ampliação NineGrid animada CompositionNineGridBrush CompositionNineGridBrush
Pintar uma área com uma cadeia de permuta SwapChainPanel CompositionSurfaceBrush com interoperabilidade de cadeia de permuta
Pintar uma área com um vídeo MediaElement CompositionSurfaceBrush com interoperabilidade de mídia
Pintar uma área com desenho 2D personalizado CanvasControl do Win2D CompositionSurfaceBrush com interoperabilidade de Win2D
Pintar uma área com máscara não animada Usar formas XAML para definir uma máscara CompositionMaskBrush
Pintar uma área com uma máscara animada CompositionMaskBrush CompositionMaskBrush
Pintar uma área com um efeito de filtro animado CompositionEffectBrush CompositionEffectBrush
Pintar uma área com um efeito aplicado aos pixels de tela de fundo CompositionBackdropBrush CompositionBackdropBrush

Interoperação nativa de composição entre DirectX e Direct2D com BeginDraw e EndDraw

Interoperabilidade do pincel XAML com XamlCompositionBrushBase