Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Все видимое на экране в приложении WinUI отображается, так как оно было окрашено кистью. Кисти позволяют рисовать объекты пользовательского интерфейса с содержимым, начиная от простых сплошных цветов до изображений, рисунков и сложных цепочек эффектов. В этом разделе рассматриваются понятия живописи с помощью CompositionBrush.
При работе с приложением WinUI XAML вы можете окрасить UIElement с помощью кисти XAML или CompositionBrush. Как правило, проще выбрать кисть XAML, если сценарий уже поддерживается одним из них. Например, анимация цвета кнопки или изменение заливки текста или фигуры изображением. Если вам нужно что-то, что не поддерживается кистью XAML, например анимированная маска, анимированное девяти-ячейковое растяжение или цепочка эффектов, можно использовать CompositionBrush для рисования UIElement через XamlCompositionBrushBase.
При работе с визуальным слоем необходимо использовать CompositionBrush для рисования области SpriteVisual.
- Prerequisites
-
Рисование с помощью CompositionBrush
- Покрасить сплошным цветом
- Краска с линейным градиентом
- Краска с радиальным градиентом
- Краска с изображением
- Рисование с помощью пользовательского рисунка
- Рисование с помощью видео
- Краска с эффектом фильтра
- Рисуйте с помощью CompositionBrush с маской прозрачности
- Рисование с использованием CompositionBrush с методом растяжения NineGrid
- Краска с помощью фоновых пикселей
- Объединение compositionBrushes
- Использование кисти XAML и CompositionBrush
- Связанные разделы
Необходимые условия
В этом обзоре предполагается, что вы знакомы со структурой базового приложения композиции, как описано в обзоре визуального слоя.
Рисование с помощью CompositionBrush
Объект CompositionBrush "красит" область со своими выходными данными. Разные кисти дают разные результаты. Некоторые инструменты для рисования закрашивают область сплошным цветом, другие используют градиент, изображение, пользовательский узор или эффект. Существуют также специализированные кисти, которые изменяют поведение других кистей. Например, маску непрозрачности можно использовать для управления областью, которую будет окрашивать CompositionBrush, а сетку из девяти частей можно использовать для управления растяжением, применяемым к CompositionBrush при рисовании области. CompositionBrush может быть одним из следующих типов:
| Класс | Сведения |
|---|---|
| CompositionColorBrush | Закрашивает область сплошным цветом |
| CompositionSurfaceBrush | Рисует область с содержимым ICompositionSurface |
| CompositionEffectBrush | Закрашивает область, используя содержимое эффекта композиции. |
| CompositionMaskBrush | Рисует изображение с помощью CompositionBrush с маской прозрачности |
| CompositionNineGridBrush | Рисует область с помощью CompositionBrush, используя растяжение NineGrid |
| CompositionLinearGradientBrush | Красит область с линейным градиентом |
| CompositionRadialGradientBrush | Красит область с радиальным градиентом |
| CompositionBackdropBrush | Рисует область путем выборки фоновых пикселей из приложения или пикселей непосредственно за окном приложения на рабочем столе. Используется в качестве входных данных для другого CompositionBrush, например CompositionEffectBrush |
Краска с сплошным цветом
CompositionColorBrush закрашивает область однородным цветом. Существует множество способов указать цвет SolidColorBrush. Например, можно указать свои альфа-, красные, синие и зеленые каналы (ARGB) или использовать один из предопределенных цветов, предоставляемых классом Colors .
На следующем рисунке и в коде показано небольшое визуальное дерево для создания прямоугольника, обведенного черной кистью и закрашенного сплошной кистью с цветом 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);
Краска с линейным градиентом
КомпозицияLinearGradientBrush рисует область с линейным градиентом. Линейный градиент объединяет два или более цветов по линии, градиентная ось. Объекты GradientStop используются для указания цветов в градиенте и их позициях.
На следующем рисунке и в коде показан SpriteVisual, нарисованный с помощью LinearGradientBrush с 2 остановками, используя красный и желтый цвета.
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);
Краска с радиальным градиентом
CompositionRadialGradientBrush рисует область с радиальным градиентом. Радиальный градиент сочетает два или более цветов с градиентом, начиная с центра эллипса и заканчивая радиусом эллипса. Объекты GradientStop используются для определения цветов и их расположения в градиенте.
На следующем рисунке и коде показан фрагмент SpriteVisual, нарисованный с помощью RadialGradientBrush с 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);
Рисовать с помощью изображения
Объект CompositionSurfaceBrush заполняет область пикселями, отображаемыми на ICompositionSurface. Например, объект CompositionSurfaceBrush можно использовать для закрашивания области изображением, визуализированным на ICompositionSurface, используя API LoadedImageSurface.
На следующем рисунке и в коде показан SpriteVisual, окрашенный с растровым изображением лакрицы, отрендеренным на ICompositionSurface с помощью LoadedImageSurface. Свойства CompositionSurfaceBrush можно использовать для растяжения и выравнивания растрового изображения в пределах визуала.
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);
Рисование с помощью пользовательского рисунка
CompositionSurfaceBrush также может использоваться для закрашивания области пикселями из ICompositionSurface, отрисованного с помощью Win2D (или D2D).
В следующем коде показан SpriteVisual, на котором отображается текст, отрисованный на ICompositionSurface с помощью Win2D. Чтобы использовать Win2D с WinUI, установите пакет NuGet Microsoft.Graphics.Win2D в проекте.
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);
Аналогично, CompositionSurfaceBrush также можно использовать для рисования объекта SpriteVisual с помощью SwapChain и взаимодействия с Win2D. Этот образец предоставляет пример использования Win2D для рисования SpriteVisual с использованием swapchain.
Рисование с помощью видео
CompositionSurfaceBrush также можно использовать для закрашивания области пикселями с поверхности ICompositionSurface, рендеренной с помощью видео, загруженного через класс MediaPlayer.
В следующем коде показано SpriteVisual с загруженным на 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);
Краска с эффектом фильтра
CompositionEffectBrush рисует область с выходными данными CompositionEffect. Эффекты в визуальном слое могут рассматриваться как эффекты фильтров, которые можно анимировать, применяемые к коллекции исходного содержимого, такого как цвета, градиенты, изображения, видео, цепочки смены кадров, регионы пользовательского интерфейса или деревья визуальных элементов. Исходное содержимое обычно указывается с помощью другого CompositionBrush.
На следующем изображении и в коде показан SpriteVisual с изображением кота, к которому применен эффект фильтра десатурации.
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);
Дополнительные сведения о создании эффекта с помощью CompositionBrushes см. в разделе "Эффекты" в визуальном слое
Красьте при помощи CompositionBrush с примененной маской непрозрачности
CompositionMaskBrush рисует область с CompositionBrush с маской непрозрачности, применённой к нему. Источником маски непрозрачности может быть любой CompositionBrush типа CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush или CompositionNineGridBrush. Маска непрозрачности должна быть указана как CompositionSurfaceBrush.
На следующем рисунке и в коде показан SpriteVisual, окрашенный с использованием CompositionMaskBrush. Источником маски является CompositionLinearGradientBrush, который маскируется, чтобы выглядеть как круг, используя изображение круга в качестве маски.
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);
Краска с помощью CompositionBrush с помощью stretch NineGrid
CompositionNineGridBrush рисует область при помощи CompositionBrush. Эта кисть растягивается с использованием метафоры девяти-сеток. Метафора с девятью ячейками позволяет растягивать края и уголки CompositionBrush иначе, чем его центр. Источник девятисетевого растяжения может быть любой CompositionBrush типа CompositionColorBrush, CompositionSurfaceBrush или CompositionEffectBrush.
В следующем коде показан SpriteVisual, окрашенный с использованием CompositionNineGridBrush. Источник маски - это CompositionSurfaceBrush, растянутый с помощью сетки 3x3.
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);
Рисуйте, используя фоновые пиксели
CompositionBackdropBrush закрашивает область содержимым, находящимся за этой областью. CompositionBackdropBrush никогда не используется самостоятельно, но вместо этого используется в качестве входных данных для другого CompositionBrush, как EffectBrush. Например, используя CompositionBackdropBrush в качестве входа для эффекта размытия, можно достичь эффекта матового стекла.
В следующем коде показано небольшое визуальное дерево для создания изображения с использованием CompositionSurfaceBrush и эффектом матового стекла поверх изображения. Наложение матированного стекла создается путем размещения SpriteVisual, заполненного эффектом Brush, над изображением. EffectBrush использует CompositionBackdropBrush в качестве входных данных для эффекта размытия.
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);
Объединение compositionBrushes
Ряд композиционных кистей использует другие композиционные кисти в качестве вводных данных. Например, с помощью метода SetSourceParameter можно задать другой CompositionBrush в качестве входных данных в CompositionEffectBrush. В таблице ниже приведены поддерживаемые сочетания CompositionBrushes. Обратите внимание, что использование неподдерживаемой комбинации приведет к возникновению исключения.
| Щетка | EffectBrush.SetSourceParameter() | MaskBrush.Mask | MaskBrush.Source | NineGridBrush.Source |
|---|---|---|---|---|
| CompositionColorBrush | ДА | ДА | ДА | ДА |
| CompositionLinear Градиентная Кисть |
ДА | ДА | ДА | НЕТ |
| CompositionSurfaceBrush | ДА | ДА | ДА | ДА |
| CompositionEffectBrush | НЕТ | НЕТ | ДА | НЕТ |
| Класс CompositionMaskBrush (Кисть с маской компоновки) | НЕТ | НЕТ | НЕТ | НЕТ |
| CompositionNineGridBrush | ДА | ДА | ДА | НЕТ |
| CompositionBackdropBrush | ДА | НЕТ | НЕТ | НЕТ |
Использование кисти XAML по сравнению с CompositionBrush
В следующей таблице приводится список сценариев и указания, когда следует использовать кисть XAML или Composition при рисовании UIElement или SpriteVisual в вашем приложении.
Замечание
Если для XAML UIElement предлагается CompositionBrush, предполагается, что CompositionBrush упакован с помощью XamlCompositionBrushBase.
| Сценарий | XAML UIElement | Композиция SpriteVisual |
|---|---|---|
| Закрасьте область сплошным цветом | Solidcolorbrush | CompositionColorBrush |
| Рисование области с анимированным цветом | Solidcolorbrush | CompositionColorBrush |
| Закрасьте область с использованием статического градиента. | LinearGradientBrush | CompositionLinearGradientBrush |
| Покраска области с анимированными точками градиента | CompositionLinearGradientBrush | CompositionLinearGradientBrush |
| Рисование области изображением | ImageBrush | CompositionSurfaceBrush |
| Рисование области с помощью веб-страницы | WebView2 | N/A |
| Рисование области с изображением с помощью stretch NineGrid | Элемент управления изображением | CompositionNineGridBrush |
| Рисование области с анимацией растягивания по схеме NineGrid | CompositionNineGridBrush | CompositionNineGridBrush |
| Окрасить область с помощью цепочки обмена кадрами | SwapChainPanel | CompositionSurfaceBrush с swapchain interop |
| Рисование области с помощью видео | MediaPlayerElement | CompositionSurfaceBrush с взаимодействием с мультимедиа |
| Закрасить область при помощи пользовательского 2D-рисунка | CanvasControl из Win2D | CompositionSurfaceBrush с поддержкой Win2D interop |
| Закрасить область неанимированной маской | Определение маски с помощью фигур XAML | CompositionMaskBrush |
| Рисование области с анимированной маской | CompositionMaskBrush | CompositionMaskBrush |
| Рисование области с эффектом анимированного фильтра | CompositionEffectBrush | CompositionEffectBrush |
| Закрасьте область с применением эффекта к фоновым пикселям | CompositionBackdropBrush | CompositionBackdropBrush |
Связанные разделы
Создание собственного взаимодействия DirectX и Direct2D с BeginDraw и EndDraw
Windows developer