Pennelli di composizione
Tutto ciò che è visibile sullo schermo da un'applicazione UWP è visibile perché è stato disegnato da un pennello. I pennelli consentono di disegnare oggetti dell'interfaccia utente con contenuto che va da colori semplici a tinta unita a immagini o disegni a catena di effetti complessi. Questo argomento presenta i concetti relativi alla pittura con CompositionBrush.
Si noti che, quando si usa l'app UWP XAML, è possibile scegliere di disegnare un oggetto UIElement con un pennello XAML o con un oggetto CompositionBrush. In genere, è più semplice e consigliabile scegliere un pennello XAML se lo scenario è supportato da un pennello XAML. Ad esempio, animando il colore di un pulsante oppure modificando il riempimento di un testo o una forma con un'immagine. D'altra parte, se si sta provando a fare qualcosa che non è supportato da un pennello XAML come disegnare con una maschera animata o un tratto di griglia a nove animato o una catena di effetti, è possibile usare un oggetto CompositionBrush per disegnare un oggetto UIElement tramite XamlCompositionBrushBase.
Quando si lavora con il livello Visual, è necessario usare un oggetto CompositionBrush per disegnare l'area di un oggetto SpriteVisual.
- Prerequisiti
- Disegnare con CompositionBrush
- Disegnare con un colore a tinta unita
- Disegnare con una sfumatura lineare
- Disegnare con una sfumatura radiale
- Disegnare con un'immagine
- Disegnare con un disegno personalizzato
- Disegnare con un video
- Disegnare con un effetto filtro
- Disegnare con un oggetto CompositionBrush con una maschera di opacità
- Disegnare con un oggetto CompositionBrush usando l'estensione NineGrid
- Disegnare con pixel di sfondo
- Combinazione di CompositionBrushes
- Uso di un pennello XAML e di CompositionBrush
- Argomenti correlati
Prerequisiti
Questa panoramica presuppone di avere familiarità con la struttura di un'applicazione Composition di base, come descritto nella panoramica sul livello Visual.
Disegnare con un oggetto CompositionBrush
Un oggetto CompositionBrush "disegna" un'area con il relativo output. Tipi di pennelli diversi producono output diversi. Alcuni pennelli disegnano un'area con un colore a tinta unita, altre con una sfumatura, un'immagine, un disegno personalizzato o un effetto. Esistono anche pennelli specializzati che modificano il comportamento di altri pennelli. Ad esempio, la maschera di opacità può essere usata per controllare l'area disegnata da un oggetto CompositionBrush o una griglia a nove per controllare l'estensione applicata a un oggetto CompositionBrush quando si disegna un'area. CompositionBrush può essere di uno dei tipi seguenti:
Classe | Dettagli | Introdotto in |
---|---|---|
CompositionColorBrush | Disegna un'area con un colore a tinta unita | Windows 10 versione 1511 (SDK 10586) |
CompositionSurfaceBrush | Disegna un'area con il contenuto di un oggetto ICompositionSurface | Windows 10 versione 1511 (SDK 10586) |
CompositionEffectBrush | Disegna un'area con il contenuto di un effetto di composizione | Windows 10 versione 1511 (SDK 10586) |
CompositionMaskBrush | Disegna un oggetto visivo con un oggetto CompositionBrush con una maschera di opacità | Windows 10 versione 1607 (SDK 14393) |
CompositionNineGridBrush | Disegna un'area con un oggetto CompositionBrush usando un'estensione NineGrid | Windows 10 versione 1607 (SDK 14393) |
CompositionLinearGradientBrush | Disegna un'area con una sfumatura lineare | Windows 10 versione 1709 (SDK 16299) |
CompositionRadialGradientBrush | Disegna un'area con una sfumatura radiale | Windows 10 versione 1903 (Insider Preview SDK) |
CompositionBackdropBrush | Disegna un'area eseguendo il campionamento dei pixel di sfondo dall'applicazione o dai pixel direttamente dietro la finestra dell'applicazione sul desktop. Usato come input per un altro CompositionBrush come compositionEffectBrush | Windows 10 versione 1607 (SDK 14393) |
Disegnare con un colore a tinta unita
Un oggetto CompositionColorBrush disegna un'area con un colore a tinta unita. Esistono diversi modi per specificare il colore di un oggetto SolidColorBrush. Ad esempio, è possibile specificare i relativi canali alfa, rosso, blu e verde (ARGB) o usare uno dei colori predefiniti forniti dalla classe Colors.
La figura e il codice seguenti illustrano una piccola struttura ad albero visuale per creare un rettangolo tratto con un pennello di colore nero e disegnato con un pennello a tinta unita con il valore di colore 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);
Disegnare con una sfumatura lineare
Un oggetto CompositionLinearGradientBrush disegna un'area con una sfumatura lineare. Una sfumatura lineare fonde due o più colori su una linea, l'asse delle sfumature. Gli oggetti GradientStop vengono usati per specificare i colori nella sfumatura e le relative posizioni.
La figura e il codice seguenti illustrano un oggetto SpriteVisual disegnato con linearGradientBrush con 2 arresti usando un colore rosso e giallo.
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);
Disegnare con una sfumatura radiale
Un oggetto CompositionRadialGradientBrush disegna un'area con una sfumatura radiale. Una sfumatura radiale fonde due o più colori con la sfumatura a partire dal centro dell'ellisse e termina con il raggio dell'ellisse. Gli oggetti GradientStop vengono usati per definire i colori e la relativa posizione nella sfumatura.
La figura e il codice seguenti illustra un oggetto SpriteVisual disegnato con radialgradientBrush con 2 gradienti.
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);
Disegnare con un'immagine
Un oggetto CompositionSurfaceBrush disegna un'area con pixel di cui viene eseguito il rendering in un oggetto ICompositionSurface. Ad esempio, un oggetto CompositionSurfaceBrush può essere usato per disegnare un'area con un'immagine sottoposta a rendering su una superficie ICompositionSurface usando l'API LoadedImageSurface.
La figura e il codice seguenti illustrano un oggetto SpriteVisual disegnato con una bitmap di colore liquirizia di cui viene eseguito il rendering in un oggetto ICompositionSurface usando LoadedImageSurface. Le proprietà di CompositionSurfaceBrush possono essere usate per estendere e allineare la bitmap all'interno dei limiti dell'oggetto visivo.
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);
Disegnare con un disegno personalizzato
Un oggetto CompositionSurfaceBrush può essere usato anche per disegnare un'area con pixel da un oggetto ICompositionSurface sottoposto a rendering tramite Win2D (o D2D).
Il codice seguente mostra un oggetto SpriteVisual disegnato con una sequenza di testo di cui è stato eseguito il rendering in un oggetto ICompositionSurface usando Win2D. Si noti che per usare Win2D è necessario includere il pacchetto NuGet Win2D nel progetto.
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);
Analogamente, CompositionSurfaceBrush può essere usato anche per disegnare uno SpriteVisual con interoperabilità Win2D con SwapChain. Questo esempio spiega come usare Win2D per disegnare un oggetto SpriteVisual con una swapchain.
Disegnare con un video
Un CompositionSurfaceBrush può essere usato anche per disegnare un'area con pixel da un oggetto ICompositionSurface sottoposto a rendering usando un video caricato tramite la classe MediaPlayer.
Il codice seguente mostra un oggetto SpriteVisual disegnato con un video caricato in un oggetto 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);
Disegnare con un effetto filtro
Un CompositionEffectBrush disegna un'area con output di CompositionEffect. Gli effetti nel livello visivo possono essere considerati come effetti di filtro animabili applicati a una raccolta di contenuti di origine, ad esempio colori, sfumature, immagini, video, swapchain, aree dell'interfaccia utente o alberi degli oggetti visivi. Il contenuto di origine viene in genere specificato usando un altro CompositionBrush.
La figura e il codice seguenti illustrano un oggetto SpriteVisual disegnato con un'immagine di un gatto con effetto filtro di desaturazione applicato.
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);
Per altre informazioni sulla creazione di un effetto tramite CompositionBrushes, vedere Effetti nel livello visivo
Disegnare con un oggetto CompositionBrush con una maschera di opacità applicata
Un CompositionMaskBrush disegna un'area con un CompositionBrush con una maschera di opacità applicata. L'origine della maschera di opacità può essere qualsiasi CompositionBrush di tipo CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush o CompositionNineGridBrush. La maschera di opacità deve essere specificata come CompositionSurfaceBrush.
La figura e il codice seguenti illustrano un oggetto SpriteVisual disegnato con CompositionMaskBrush. L'origine della maschera è un CompositionLinearGradientBrush che viene mascherato per apparire come un cerchio usando un'immagine di cerchio come maschera.
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);
Disegnare con un oggetto CompositionBrush usando l'estensione NineGrid
Un CompositionNineGridBrush disegna un'area con un CompositionBrush esteso usando la metafora a nove griglie. La metafora a nove griglie consente di estendere i bordi e gli angoli di un CompositionBrush in modo diverso rispetto al suo centro. L'origine dell'estensione a nove griglie può essere eseguita da qualsiasi CompositionBrush di tipo CompositionColorBrush, CompositionSurfaceBrush o CompositionEffectBrush.
Il codice seguente mostra un oggetto SpriteVisual disegnato con CompositionNineGridBrush. L'origine della maschera è un CompositionSurfaceBrush che viene esteso usando una griglia Nine.
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);
Disegnare con pixel di sfondo
Un CompositionBackdropBrush disegna un'area con il contenuto dietro l'area. Un CompositionBackdropBrush non viene mai usato autonomamente, ma viene invece usato come input per un altro CompositionBrush come EffectBrush. Ad esempio, usando CompositionBackdropBrush come input per un effetto sfocatura, è possibile ottenere un effetto vetro smerigliato.
Il codice seguente mostra una piccola struttura ad albero visuale per creare un'immagine usando CompositionSurfaceBrush e una sovrimpressione di vetro smerigliato sopra l'immagine. La sovrimpressione di vetro smerigliato viene creata posizionando uno SpriteVisual pieno di EffectBrush sopra l'immagine. EffectBrush usa CompositionBackdropBrush come input per l'effetto sfocatura.
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);
Combinazione di CompositionBrushes
Alcuni oggetti CompositionBrushes usano altri oggetti CompositionBrushes come input. Ad esempio, l'uso del metodo SetSourceParameter può essere usato per impostare un altro CompositionBrush come input su CompositionEffectBrush. La tabella seguente illustra le combinazioni supportate di CompositionBrushes. Si noti che l'uso di una combinazione non supportata genererà un'eccezione.
Brush | EffectBrush.SetSourceParameter() | MaskBrush.Mask | 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 |
CompositionMaskBrush | NO | NO | NO | NO |
CompositionNineGridBrush | SÌ | SÌ | SÌ | NO |
CompositionBackdropBrush | SÌ | NO | NO | NO |
Uso di un pennello XAML e di CompositionBrush
La tabella seguente fornisce un elenco di scenari e indica se è previsto l'uso del pennello XAML o Composition quando si disegna un oggetto UIElement o SpriteVisual nell'applicazione.
Nota
Se per un oggetto UIElement XAML viene suggerito un oggetto CompositionBrush, si presuppone che CompositionBrush venga creato in un pacchetto usando XamlCompositionBrushBase.
Scenario | XAML UIElement | SpriteVisual di composizione |
---|---|---|
Disegnare un'area con un colore a tinta unita | SolidColorBrush | CompositionColorBrush |
Disegnare un'area con un colore animato | SolidColorBrush | CompositionColorBrush |
Disegnare un'area con una sfumatura statica | LinearGradientBrush | CompositionLinearGradientBrush |
Disegnare un'area con interruzioni sfumature animate | CompositionLinearGradientBrush | CompositionLinearGradientBrush |
Disegnare un'area con un'immagine | ImageBrush | CompositionSurfaceBrush |
Disegnare un'area con una pagina Web | WebViewBrush | N/D |
Disegnare un'area con un'immagine usando l'estensione NineGrid | Controllo Image | CompositionNineGridBrush |
Disegnare un'area con estensione NineGrid animata | CompositionNineGridBrush | CompositionNineGridBrush |
Disegnare un'area con una swapchain | SwapChainPanel | CompositionSurfaceBrush con interoperabilità swapchain |
Disegnare un'area con un video | MediaElement | CompositionSurfaceBrush con interoperabilità multimediale |
Disegnare un'area con un disegno 2D | CanvasControl da Win2D | CompositionSurfaceBrush con interoperabilità Win2D |
Disegnare un'area con una maschera non animata | Usare forme XAML per definire una maschera | CompositionMaskBrush |
Disegnare un'area con una maschera non animata | CompositionMaskBrush | CompositionMaskBrush |
Disegnare un'area con un effetto filtro animato | CompositionEffectBrush | CompositionEffectBrush |
Disegnare un'area con un effetto applicato ai pixel di sfondo | CompositionBackdropBrush | CompositionBackdropBrush |
Argomenti correlati
Interoperabilità DirectX e Direct2D nativa della composizione con BeginDraw e EndDraw
Interoperabilità del pennello XAML con XamlCompositionBrushBase