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
- Pintar com CompositionBrush
- Pinte com uma cor sólida
- Pintar com um gradiente linear
- Pinte com um gradiente radial
- Pintar com uma imagem
- Pintar com um desenho personalizado
- Pintar com um vídeo
- Pinte com efeito de filtro
- Pintar com uma composiçãoPincel com uma máscara de opacidade
- Pinte com um CompositionBrush usando o alongamento NineGrid
- Pintar usando pixels de fundo
- Combinando CompositionBrushes
- Usando um pincel XAML vs. CompositionBrush
- Tópicos relacionados
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.
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.
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.
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.
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.
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.
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 |
Tópicos Relacionados
Interoperabilidade nativa do DirectX e Direct2D da composição com BeginDraw e EndDraw
Interoperabilidade de pincel XAML com XamlCompositionBrushBase