Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wszystko widoczne na ekranie w aplikacji WinUI jest widoczne, ponieważ zostało namalowane przez szczotkę. Pędzle umożliwiają malowanie obiektów interfejsu użytkownika z zawartością od prostych, jednolitych kolorów do obrazów, rysunków i łańcuchów złożonych efektów. W tym temacie przedstawiono koncepcje malowania za pomocą CompositionBrush.
Podczas pracy z aplikacją WinUI XAML możesz pomalować element UIElement za pomocą pędzla XAML lub CompositionBrush. Zazwyczaj łatwiej jest wybrać pędzel XAML, jeśli twój scenariusz jest już obsługiwany przez jeden. Na przykład animowanie koloru przycisku lub zmienianie wypełnienia tekstu lub kształtu obrazem. Jeśli potrzebujesz czegoś, co nie jest obsługiwane przez pędzel XAML, takiego jak animowana maska, animowane rozciąganie dziewięciosiatki lub łańcuch efektów, możesz użyć CompositionBrush do malowania UIElement za pośrednictwem XamlCompositionBrushBase.
Podczas pracy z warstwą wizualną należy użyć narzędzia CompositionBrush do malowania obszaru SpriteVisual.
- Prerequisites
-
Malowanie z CompositionBrush
- Maluj kolorem jednolitym
- Malowanie z gradientem liniowym
- Malowanie gradientem promieniowym
- Malowanie przy użyciu obrazu
- Maluj niestandardowym rysunkiem
- Malowanie za pomocą wideo
- Malowanie z efektem filtru
- Malowanie za pomocą CompositionBrush z maską nieprzezroczystości
- Maluj za pomocą CompositionBrush z wykorzystaniem siatki NineGrid
- Malowanie przy użyciu pikseli tła
- Łączenie CompositionBrushes
- Używanie pędzla XAML a pędzla Composition
- Tematy pokrewne
Wymagania wstępne
W tym omówieniu założono, że znasz strukturę podstawowej aplikacji kompozycji, zgodnie z opisem w omówieniu warstwy wizualnej.
Malowanie za pomocą CompositionBrush
CompositionBrush "maluje" obszar wynikiem swojej pracy. Różne szczotki/prędzle mają różne rodzaje wyników. Niektóre pędzle malują obszar o stałym kolorze, inne z gradientem, obrazem, rysunkiem niestandardowym lub efektem. Istnieją również wyspecjalizowane szczotki, które modyfikują zachowanie innych pędzli. Na przykład maska krycia może służyć do kontrolowania, który obszar jest malowany przez CompositionBrush, a siatka dziewięciu części może być użyta do kontrolowania rozciągnięcia zastosowanego do pędzla CompositionBrush podczas malowania obszaru. CompositionBrush może być jednym z następujących typów.
| Klasa | Szczegóły |
|---|---|
| CompositionColorBrush | Maluje obszar o stałym kolorze |
| CompositionSurfaceBrush | Maluje obszar z zawartością elementu ICompositionSurface |
| PędzelEfektówKompozycji | Maluje obszar z zawartością efektu kompozycji |
| Pędzel maski kompozycji | Maluje element wizualny za pomocą CompositionBrush z maską przezroczystości |
| Kompozycja: NineGridBrush | Maluje obszar za pomocą CompositionBrush z wykorzystaniem rozciągania NineGrid |
| CompositionLinearGradientBrush | Maluje obszar z gradientem liniowym |
| CompositionRadialGradientBrush | Maluje obszar z gradientem promieniowym |
| CompositionBackdropBrush | Malowanie obszaru przez pobranie próbek pikseli tła z aplikacji lub z pikseli bezpośrednio znajdujących się za oknem aplikacji na pulpicie. Używane jako dane wejściowe do innego CompositionBrush, takiego jak CompositionEffectBrush. |
Malowanie jednolitym kolorem
Element CompositionColorBrush maluje obszar jednolitym kolorem. Istnieje wiele sposobów definiowania koloru SolidColorBrush. Można na przykład określić kanały alfa, czerwone, niebieskie i zielone (ARGB) lub użyć jednego ze wstępnie zdefiniowanych kolorów dostarczonych przez klasę Kolory .
Na poniższej ilustracji i w kodzie przedstawiono małe drzewo wizualne umożliwiające utworzenie prostokąta, który jest obrysowany pędzlem w kolorze czarnym i wypełniany stałym kolorem o wartości 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);
Maluj z użyciem gradientu liniowego
CompositionLinearGradientBrush służy do malowania obszaru gradientem liniowym. Gradient liniowy łączy dwa lub więcej kolorów wzdłuż osi gradientu. Obiekty GradientStop służą do określania kolorów gradientu i ich położenia.
Na poniższej ilustracji i w kodzie przedstawiono SpriteVisual malowany przy użyciu LinearGradientBrush z 2 przystankami w kolorze czerwonym i żółtym.
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);
Malowanie gradientem promieniowym
CompositionRadialGradientBrush maluje obszar za pomocą gradientu promieniowego. Gradient promieniowy łączy co najmniej dwa kolory, zaczynając od środka elipsy i kończąc na jej promieniu. Obiekty GradientStop służą do definiowania kolorów i ich lokalizacji w gradientzie.
Na poniższej ilustracji i kodzie przedstawiono SpriteVisual malowany za pomocą RadialGradientBrush z 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);
Malowanie przy użyciu obrazu
CompositionSurfaceBrush służy do malowania powierzchni pikselami renderowanymi na ICompositionSurface. Na przykład element CompositionSurfaceBrush może służyć do malowania obszaru z obrazem renderowanym na powierzchnię ICompositionSurface za pomocą API LoadedImageSurface.
Na poniższej ilustracji i w kodzie przedstawiono SpriteVisual pomalowany bitmapą z lukrecją, renderowany na ICompositionSurface, używając LoadedImageSurface. Właściwości compositionSurfaceBrush można użyć do rozciągania i wyrównania mapy bitowej w granicach wizualizacji.
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);
Maluj za pomocą własnego rysunku
Element CompositionSurfaceBrush może również służyć do malowania obszaru z pikselami z elementu ICompositionSurface renderowanego przy użyciu win2D (lub D2D).
Poniższy kod przedstawia SpriteVisual malowany z uruchomionym fragmentem tekstu renderowanym na powierzchni ICompositionSurface przy użyciu Win2D. Aby użyć win2D z winUI, zainstaluj pakiet NuGet Microsoft.Graphics.Win2D w projekcie.
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);
Podobnie, pędzla CompositionSurfaceBrush można użyć do malowania obiektu SpriteVisual przy użyciu SwapChain i międzyoperacyjności Win2D. Ten przykład przedstawia przykład użycia Win2D do malowania SpriteVisual za pomocą swapchain.
Malowanie za pomocą wideo
Element CompositionSurfaceBrush może również służyć do malowania obszaru z pikselami z elementu ICompositionSurface renderowanego przy użyciu wideo załadowanego za pośrednictwem klasy MediaPlayer .
Poniższy kod przedstawia SpriteVisual renderowany za pomocą wideo załadowanego do 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);
Malowanie z efektem filtru
CompositionEffectBrush maluje obszar za pomocą wyniku działania CompositionEffect. Efekty w warstwie wizualnej mogą być uważane za animowane efekty filtru stosowane do kolekcji zawartości źródłowej, takiej jak kolory, gradienty, obrazy, filmy wideo, swapchainy, regiony interfejsu użytkownika lub drzewa elementów wizualnych. Zawartość źródłowa jest zwykle określana przy użyciu innego elementu CompositionBrush.
Na poniższej ilustracji i kodzie przedstawiono SpriteVisual z obrazem kota, na który nałożono efekt filtru desaturacji.
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);
Aby uzyskać więcej informacji na temat tworzenia efektu przy użyciu pędzli kompozycji, zobacz Efekty w warstwie wizualnej
Maluj za pomocą CompositionBrush z nałożoną maską krycia
Pędzel maski kompozycyjnej maluje obszar pędzlem kompozycji ze stosowaną maską nieprzezroczystości. Źródłem maski nieprzezroczystości może być dowolny CompositionBrush typu CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush lub CompositionNineGridBrush. Maska nieprzezroczystości musi być określona jako CompositionSurfaceBrush.
Na poniższej ilustracji i w kodzie pokazano SpriteVisual pomalowany za pomocą CompositionMaskBrush. Źródłem maski jest CompositionLinearGradientBrush, który zostaje zamaskowany, aby przypominał okrąg, używając obrazu okręgu jako maski.
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);
Malowanie przy użyciu CompositionBrush z użyciem rozciągania NineGrid
CompositionNineGridBrush maluje obszar za pomocą CompositionBrush, który jest rozciągany przy użyciu metafory dziewięciosiatkowej. Metafora dziewięciu kwadratów pozwala rozciągać krawędzie i rogi CompositionBrush inaczej niż jej środek. Źródłem dziewięciosiatkowego rozciągnięcia może być dowolny CompositionBrush typu CompositionColorBrush, CompositionSurfaceBrush lub CompositionEffectBrush.
Poniższy kod przedstawia SpriteVisual pomalowany za pomocą pędzla CompositionNineGridBrush. Źródłem maski jest CompositionSurfaceBrush, który rozciągnięto za pomocą Nine-Grid.
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);
Malowanie przy użyciu pikseli tła
CompositionBackdropBrush maluje obszar za pomocą zawartości znajdującej się za nim. KompozycjaBackdropBrush nigdy nie jest używana samodzielnie, lecz jako dane wejściowe dla innego pędzla kompozycji, takiego jak EffectBrush. Na przykład, używając elementu CompositionBackdropBrush jako danych wejściowych do efektu Blur, można osiągnąć efekt szkła matowego.
Poniższy kod przedstawia małe drzewo wizualne do utworzenia obrazu przy użyciu elementu CompositionSurfaceBrush i matowej szklanej nakładki nad obrazem. Matowa nakładka ze szkła jest tworzona przez umieszczenie SpriteVisual wypełnionego EffectBrush nad obrazem. EffectBrush używa CompositionBackdropBrush jako wejścia do efektu rozmycia.
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);
Łączenie kompozycjiBrushes
Wiele pędzli kompozycji używa innych pędzli kompozycji jako danych wejściowych. Na przykład za pomocą metody SetSourceParameter można ustawić inny element CompositionBrush jako dane wejściowe elementu CompositionEffectBrush. Poniższa tabela przedstawia obsługiwane kombinacje CompositionBrushes. Należy pamiętać, że użycie nieobsługiwanej kombinacji spowoduje zgłoszenie wyjątku.
| Pędzel | EffectBrush.SetSourceParameter() | MaskBrush.Mask | MaskBrush.Source | NineGridBrush.Source |
|---|---|---|---|---|
| CompositionColorBrush | TAK | TAK | TAK | TAK |
| Kompozycja liniowa GradientBrush |
TAK | TAK | TAK | NIE |
| CompositionSurfaceBrush | TAK | TAK | TAK | TAK |
| CompositionEffectBrush | NIE | NIE | TAK | NIE |
| Pędzel maski kompozycji | NIE | NIE | NIE | NIE |
| Kompozycja NineGridBrush | TAK | TAK | TAK | NIE |
| KompozycjaBackdropBrush | TAK | NIE | NIE | NIE |
Używanie pędzla XAML kontra CompositionBrush
Poniższa tabela zawiera listę scenariuszy i określa, czy zaleca się użycie pędzla XAML lub pędzla Kompozycji podczas malowania komponentu UIElement lub SpriteVisual w aplikacji.
Uwaga / Notatka
Jeśli sugerowany jest CompositionBrush dla elementu UIElement XAML, zakłada się, że CompositionBrush jest spakowany za pomocą XamlCompositionBrushBase.
| Scenario | Element interfejsu użytkownika XAML | Kompozycja SpriteVisual |
|---|---|---|
| Malowanie obszaru o stałym kolorze | SolidColorBrush | CompositionColorBrush |
| Malowanie obszaru z animowanym kolorem | SolidColorBrush | CompositionColorBrush |
| Malowanie obszaru ze statycznym gradientem | LinearGradientBrush | CompositionLinearGradientBrush |
| Pomaluj obszar z animowanymi punktami gradientu | CompositionLinearGradientBrush | CompositionLinearGradientBrush |
| Malowanie obszaru z obrazem | Imagebrush | CompositionSurfaceBrush |
| Malowanie obszaru za pomocą strony internetowej | WebView2 | N/A |
| Malowanie obszaru z obrazem przy użyciu odcinka NineGrid | Kontrolka obrazu | KompozycjaNineGridBrush |
| Malowanie obszaru animowanym odcinkiem NineGrid | CompositionNineGridBrush | Kompozycja NineGridBrush |
| Malowanie obszaru przy użyciu swapchainu | SwapChainPanel | CompositionSurfaceBrush w/ swapchain interop |
| Malowanie obszaru za pomocą wideo | MediaPlayerElement | CompositionSurfaceBrush z współpracą mediów |
| Malowanie obszaru za pomocą niestandardowego rysunku 2D | CanvasControl z win2D | CompositionSurfaceBrush z interoperacyjnością Win2D |
| Malowanie obszaru bez animowanej maski | Definiowanie maski przy użyciu kształtów XAML | Pędzel maski kompozycji |
| Malowanie obszaru z animowaną maską | Pędzel maski kompozycji | Pędzel maski kompozycji |
| Malowanie obszaru z animowanym efektem filtru | PędzelEfektówKompozycji | PędzelEfektówKompozycji |
| Pomalowanie obszaru z efektem na pikselach tła | CompositionBackdropBrush | CompositionBackdropBrush |
Tematy pokrewne
Natywna kompozycja interop DirectX i Direct2D z BeginDraw i EndDraw