Partilhar via


Pincéis de composição

Tudo o que está visível na tela de um aplicativo UWP é visível porque foi pintado por um pincel. Os pincéis permitem que você pinte objetos de interface do usuário (UI) com conteúdo que varia de cores simples e sólidas a imagens ou desenhos a uma cadeia de efeitos complexa. 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, é mais fácil e aconselhável 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 pintar com uma máscara animada ou um alongamento animado de nove grades ou uma cadeia de efeitos, poderá usar um CompositionBrush para pintar um UIElement por meio do uso de XamlCompositionBrushBase.

Ao trabalhar com a camada Visual, um CompositionBrush deve ser usado para pintar a área de um SpriteVisual.

Pré-requisitos

Essa visão geral pressupõe que você esteja familiarizado com a estrutura de um aplicativo básico do Composition, conforme 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, imagem, desenho personalizado ou efeito. Existem também 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 uma grade de nove pode ser usada para controlar o alongamento aplicado a um CompositionBrush ao pintar uma área. CompositionBrush pode ser de um dos seguintes tipos:

Classe Detalhes Introduzido em
ComposiçãoColorBrush 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)
Pincel de efeito de composição Pinta uma área com o conteúdo de um efeito de composição Windows 10, versão 1511 (SDK 10586)
ComposiçãoMaskBrush Pinta um visual com um CompositionBrush com uma máscara de opacidade Windows 10, versão 1607 (SDK 14393)
ComposiçãoNineGridBrush Pinta uma área com um CompositionBrush usando um alongamento NineGrid Windows 10, versão 1607 (SDK 14393)
ComposiçãoLinearGradientBrush 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)
ComposiçãoBackdropBrush Pinta uma área por amostragem de pixels de plano de fundo do aplicativo ou pixels diretamente atrá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)

Pinte com uma cor sólida

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

A ilustração e o código a seguir 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.

ComposiçãoColorBrush

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. Use 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 com 2 paradas usando uma cor vermelha e amarela.

ComposiçãoLinearGradientBrush

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

Pinte 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 no centro da elipse e terminando no raio da elipse. Os 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 alcaçuz renderizado em um ICompositionSurface usando LoadedImageSurface. As propriedades de CompositionSurfaceBrush podem ser usadas para esticar e alinhar o bitmap dentro dos limites do 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 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

Um 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ê precisa incluir o pacote NuGet do Win2D em seu 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 um SwapChain usando a interoperabilidade Win2D. Este exemplo fornece um exemplo de como usar o Win2D para pintar um SpriteVisual com uma cadeia de troca.

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 por meio da 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);

Pinte com efeito de filtro

Um CompositionEffectBrush pinta uma área com a saída de um CompositionEffect. Os efeitos na camada visual podem ser considerados como efeitos de filtro animáveis aplicados a uma coleção de conteúdo de origem, como cores, gradientes, imagens, vídeos, cadeias de troca, regiões da interface do usuário ou árvores de 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 que tem o efeito de filtro de dessaturação aplicado.

Pincel de efeito de composição

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 com um CompositionBrush com máscara de opacidade aplicada

Um CompositionMaskBrush pinta uma área com um CompositionBrush com uma máscara de opacidade aplicada a ela. 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 que é mascarado para se parecer com um círculo usando uma imagem de círculo como uma máscara.

ComposiçãoMaskBrush

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

Pinte com um CompositionBrush usando o alongamento NineGrid

Um CompositionNineGridBrush pinta uma área com um CompositionBrush que é esticado usando a metáfora de nove grades. A metáfora de nove grades permite que você estique bordas e cantos de um CompositionBrush de forma diferente de seu centro. A origem do trecho de nove grades pode ser usada por qualquer CompositionBrush do tipo CompositionColorBrush, CompositionSurfaceBrush ou CompositionEffectBrush.

O código a seguir mostra um SpriteVisual pintado com um CompositionNineGridBrush. A origem da máscara é um CompositionSurfaceBrush que é esticado usando um Nine-Grid.

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 sozinho, mas é usado como uma entrada para outro CompositionBrush como um EffectBrush. Por exemplo, usando um CompositionBackdropBrush como uma entrada para um efeito Desfoque, você pode obter um efeito de vidro fosco.

O código a seguir 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 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);

Combinando CompositionBrushes

Vários CompositionBrushes usam outros CompositionBrushes como entradas. Por exemplo, o uso do método SetSourceParameter pode ser usado para definir outro CompositionBrush como uma entrada para um CompositionEffectBrush. A tabela a seguir descreve as combinações com suporte de CompositionBrushes. Observe que o uso de uma combinação sem suporte gerará uma exceção.

Pincel EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
ComposiçãoColorBrush YES YES YES YES
ComposiçãoLinear
Pincel gradiente
YES YES YES NO
CompositionSurfaceBrush YES YES YES YES
Pincel de efeito de composição NO Não YES NO
ComposiçãoMaskBrush NO NO NO NO
ComposiçãoNineGridBrush YES YES YES NO
ComposiçãoBackdropBrush YES Não NO NO

Usando um pincel XAML vs. CompositionBrush

A tabela a seguir fornece uma lista de cenários e se o uso de pincel XAML ou Composition é prescrito ao pintar um UIElement ou um SpriteVisual em seu aplicativo.

Observação

Se um CompositionBrush for sugerido para um UIElement XAML, supõe-se que o CompositionBrush seja empacotado usando um XamlCompositionBrushBase.

Cenário XAML UIElement SpriteVisual de Composição
Pinte uma área com cor sólida SolidColorBrush ComposiçãoColorBrush
Pintar uma área com cores animadas SolidColorBrush ComposiçãoColorBrush
Pintar uma área com um gradiente estático LinearGradientBrush ComposiçãoLinearGradientBrush
Pintar uma área com paradas de gradiente animadas ComposiçãoLinearGradientBrush ComposiçãoLinearGradientBrush
Pintar uma área com uma imagem ImageBrush CompositionSurfaceBrush
Pintar uma área com uma página da Web WebViewBrush N/D
Pinte uma área com uma imagem usando o alongamento NineGrid Controle de imagem ComposiçãoNineGridBrush
Pinte uma área com alongamento animado do NineGrid ComposiçãoNineGridBrush ComposiçãoNineGridBrush
Pintar uma área com uma cadeia de troca SwapChainPanel CompositionSurfaceBrush com interoperabilidade swapchain
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 Win2D
Pintar uma área com máscara não animada Usar formas XAML para definir uma máscara ComposiçãoMaskBrush
Pintar uma área com uma máscara animada ComposiçãoMaskBrush ComposiçãoMaskBrush
Pintar uma área com um efeito de filtro animado Pincel de efeito de composição Pincel de efeito de composição
Pintar uma área com um efeito aplicado aos pixels do plano de fundo ComposiçãoBackdropBrush ComposiçãoBackdropBrush

Interoperabilidade nativa do DirectX e Direct2D da composição com BeginDraw e EndDraw

Interoperabilidade de pincel XAML com XamlCompositionBrushBase