Кисти композиции

Все видимое на экране из приложения UWP отображается, так как оно было окрашено кистью. Кисти позволяют рисовать объекты пользовательского интерфейса с содержимым, начиная от простых, сплошных цветов до изображений или рисунков до сложных цепочек эффектов. В этом разделе рассматриваются понятия живописи с помощью CompositionBrush.

Обратите внимание, что при работе с приложением UWP XAML можно нарисовать UIElement с помощью кисти XAML или CompositionBrush. Как правило, проще и рекомендуется выбрать кисть XAML, если ваш сценарий поддерживается кистью XAML. Например, анимация цвета кнопки, изменение заливки текста или фигуры изображением. С другой стороны, если вы пытаетесь сделать то, что не поддерживается кистью XAML, например рисованием с анимированной маской или анимированной девятью сеткой растяжения или цепочкой эффектов, можно использовать CompositionBrush для рисования UIElement с помощью XamlCompositionBrushBase.

При работе с визуальным слоем необходимо использовать CompositionBrush для рисования области SpriteVisual.

Необходимые компоненты

В этом обзоре предполагается, что вы знакомы со структурой базового приложения композиции, как описано в обзоре визуального слоя.

Краска с помощью CompositionBrush

Объект CompositionBrush "красит" область со своими выходными данными. Разные кисти имеют разные типы выходных данных. Некоторые кисти красит область с сплошным цветом, другие с градиентом, изображением, пользовательским рисунком или эффектом. Существуют также специализированные кисти, которые изменяют поведение других кистей. Например, маску непрозрачности можно использовать для управления областью, окрашенной в CompositionBrush, или девять сетки можно использовать для управления растяжением, примененным к CompositionBrush при рисовании области. CompositionBrush может быть одним из следующих типов:

Класс Сведения Введено в
CompositionColorBrush Краска области с сплошным цветом Windows 10 версии 1511 (пакет SDK 10586)
CompositionSurfaceBrush Рисует область с содержимым ICompositionSurface Windows 10 версии 1511 (пакет SDK 10586)
CompositionEffectBrush Красит область с содержимым эффекта композиции Windows 10 версии 1511 (пакет SDK 10586)
CompositionMaskBrush Рисует визуальный элемент с помощью CompositionBrush с маской непрозрачности Windows 10 версии 1607 (пакет SDK 14393)
CompositionNineGridBrush Рисует область с помощью compositionBrush с помощью растяжения NineGrid Windows 10 версии 1607 (пакет SDK 14393)
CompositionLinearGradientBrush Красит область с линейным градиентом Windows 10 версии 1709 (пакет SDK 16299)
CompositionRadialGradientBrush Красит область с радиальным градиентом Windows 10 версии 1903 (пакет SDK для предварительной версии программы предварительной оценки)
CompositionBackdropBrush Рисует область путем выборки фоновых пикселей из приложения или пикселей непосредственно за окном приложения на рабочем столе. Используется в качестве входных данных для другого CompositionBrush, например CompositionEffectBrush Windows 10 версии 1607 (пакет SDK 14393)

Краска с сплошным цветом

КомпозицияColorBrush рисует область сплошным цветом. Существует множество способов указать цвет SolidColorBrush. Например, можно указать свои альфа-, красные, синие и зеленые каналы (ARGB) или использовать один из предопределенных цветов, предоставляемых классом Colors .

На следующем рисунке и коде показано небольшое визуальное дерево для создания прямоугольника, нарисованного черной кистью цвета и окрашенной сплошной кистью цвета, которая имеет значение цвета 0x9ACD32.

CompositionColorBrush

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

Краска с линейным градиентом

КомпозицияLinearGradientBrush рисует область с линейным градиентом. Линейный градиент объединяет два или более цветов по линии, градиентная ось. Объекты GradientStop используются для указания цветов в градиенте и их позициях.

На следующем рисунке и коде показан фрагмент SpriteVisual, нарисованный с помощью LinearGradientBrush с 2 остановкой использования красного и желтого цвета.

CompositionLinearGradientBrush

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

Краска с радиальным градиентом

КомпозицияRadialGradientBrush рисует область с радиальным градиентом. Радиальный градиент сочетает два или более цветов с градиентом, начиная с центра эллипса и заканчивая радиусом эллипса. Объекты GradientStop используются для определения цветов и их расположения в градиенте.

На следующем рисунке и коде показан фрагмент SpriteVisual, нарисованный с помощью RadialGradientBrush с 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);

Краска с изображением

Объект CompositionSurfaceBrush рисует область с пикселями, отображаемыми на ICompositionSurface. Например, для рисования области с изображением, отображаемой на поверхности ICompositionSurface с помощью API LoadedImageSurface , можно использовать КомпозициюSurface.

На следующем рисунке и коде показан фрагмент spriteVisual, нарисованный с растровым изображением ликориса, отрисованного на ICompositionSurface с помощью LoadedImageSurface. Свойства CompositionSurfaceBrush можно использовать для растяжения и выравнивания растрового изображения в пределах визуального элемента.

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

Рисование с помощью пользовательского рисунка

КомпозицияSurfaceBrush также может использоваться для рисования области с пикселями из ICompositionSurface, отрисованного с помощью Win2D (или D2D).

В следующем коде показан фрагмент spriteVisual с текстом, отображаемым на ICompositionSurface с помощью Win2D. Обратите внимание, что для использования Win2D необходимо включить пакет NuGet Win2D в проект.

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

Аналогичным образом, КомпозицияSurfaceBrush также может использоваться для рисования SpriteVisual с помощью буферной цепочки с помощью взаимодействия Win2D. В этом примере представлен пример использования Win2D для рисования spriteVisual с цепочкой буферов.

Рисование с помощью видео

КомпозицияSurfaceBrush также может использоваться для рисования области с пикселями из ICompositionSurface, отрисованного с помощью видео, загруженного через класс MediaPlayer.

В следующем коде показан фрагмент spriteVisual с видео, загруженным на 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);

Краска с эффектом фильтра

КомпозицияEffectBrush рисует область с выходными данными CompositionEffect. Эффекты в визуальном слое могут рассматриваться как анимируемые эффекты фильтра, применяемые к коллекции исходного содержимого, таких как цвета, градиенты, изображения, видео, буферы, регионы пользовательского интерфейса или деревья визуальных элементов. Исходное содержимое обычно указывается с помощью другого CompositionBrush.

На следующем рисунке и коде показан фрагмент SpriteVisual с изображением кота, который имеет примененный эффект фильтра денасации.

CompositionEffectBrush

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

Дополнительные сведения о создании эффекта с помощью CompositionBrushes см. в разделе "Эффекты" в визуальном слое

Краска с помощью CompositionBrush с примененной маской непрозрачности

КомпозицияMaskBrush рисует область с композициейBrush с маской непрозрачности, примененной к нему. Источником маски непрозрачности может быть любой CompositionBrush типа CompositionColorBrush, CompositionLinearGradientBrush, CompositionSurfaceBrush, CompositionEffectBrush или CompositionNineGridBrush. Маска непрозрачности должна быть указана как CompositionSurfaceBrush.

На следующем рисунке и коде показан фрагмент SpriteVisual с помощью CompositionMaskBrush. Источником маски является CompositionLinearGradientBrush, который маскируется, чтобы выглядеть как круг, используя изображение круга в качестве маски.

CompositionMaskBrush

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

Краска с помощью CompositionBrush с помощью stretch NineGrid

CompositionNineGridBrush рисует область с композициейBrush , которая растянута с помощью девяти сетки метафоры. Метафора с девятью сетками позволяет растягивать края и уголки композицииBrush по-разному, чем его центр. Источник девятисетевого растяжения может быть любой CompositionBrush типа CompositionColorBrush, CompositionSurfaceBrush или CompositionEffectBrush.

В следующем коде показан фрагмент SpriteVisual с помощью CompositionNineGridBrush. Источником маски является композицияSurfaceBrush, которая растянута с помощью девяти сетки.

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

Краска с помощью фоновых пикселей

КомпозицияBackdropBrush красит область с содержимым за областью. CompositionBackdropBrush никогда не используется самостоятельно, но вместо этого используется в качестве входных данных для другого CompositionBrush, как EffectBrush. Например, используя CompositionBackdropBrush в качестве входных данных в эффект Размытия, можно достичь заморозленного стеклянного эффекта.

В следующем коде показано небольшое визуальное дерево для создания изображения с помощью CompositionSurfaceBrush и подложенного стекла над изображением. Наложение заморозированного стекла создается путем размещения SpriteVisual, заполненного эффектомBrush над изображением. EffectBrush использует CompositionBackdropBrush в качестве входных данных для эффекта размытия.

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

Объединение compositionBrushes

Ряд compositionBrushes использует другие КомпозицииBrushes в качестве входных данных. Например, с помощью метода SetSourceParameter можно задать другой CompositionBrush в качестве входных данных в CompositionEffectBrush. В таблице ниже приведены поддерживаемые сочетания CompositionBrushes. Обратите внимание, что использование неподдерживаемой комбинации приведет к возникновению исключения.

Кисть EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
CompositionColorBrush Да Да Да Да
CompositionLinear
GradientBrush
Да Да Да Нет
CompositionSurfaceBrush Да Да Да Да
CompositionEffectBrush Нет Нет Да Нет
CompositionMaskBrush Нет Нет Нет Нет
CompositionNineGridBrush Да Да Да Нет
CompositionBackdropBrush Да Нет Нет Нет

Использование кисти XAML и CompositionBrush

В следующей таблице приведен список сценариев и назначение кисти XAML или Композиции при рисовании UIElement или SpriteVisual в приложении.

Примечание.

Если для xaml UIElement предлагается CompositionBrush, предполагается, что CompositionBrush упаковается с помощью XamlCompositionBrushBase.

Сценарий XAML UIElement Композиция SpriteVisual
Краска области с сплошным цветом SolidColorBrush; CompositionColorBrush
Рисование области с анимированным цветом SolidColorBrush; CompositionColorBrush
Краска области со статическим градиентом LinearGradientBrush; CompositionLinearGradientBrush
Краска области с анимированными градиентными остановками CompositionLinearGradientBrush CompositionLinearGradientBrush
Рисование области изображением ImageBrush; CompositionSurfaceBrush
Рисование области с помощью веб-страницы WebViewBrush; Н/П
Рисование области с изображением с помощью stretch NineGrid Элемент управления изображением CompositionNineGridBrush
Рисование области с анимацией NineGrid stretch CompositionNineGridBrush CompositionNineGridBrush
Краска области с цепочкой буферов SwapChainPanel КомпозицияSurfaceBrush w/swapchain interop
Рисование области с помощью видео MediaElement CompositionSurfaceBrush w/media interop
Рисование области с пользовательским 2D-рисунком CanvasControl из Win2D CompositionSurfaceBrush w/ Win2D interop
Рисование области с неанимированной маской Определение маски с помощью фигур XAML CompositionMaskBrush
Рисование области с анимированной маской CompositionMaskBrush CompositionMaskBrush
Рисование области с эффектом анимированного фильтра CompositionEffectBrush CompositionEffectBrush
Краска области с эффектом, примененным к фоновым пикселям CompositionBackdropBrush CompositionBackdropBrush

Создание собственного взаимодействия DirectX и Direct2D с BeginDraw и EndDraw

Взаимодействие кисти XAML с XamlCompositionBrushBase