組合筆刷

從 UWP 應用程式看到的所有畫面項目都是可見的,因為它是由筆刷繪製而成。 筆刷可讓您繪製使用者介面 (UI) 物件,內容從簡單、純色到影像或繪圖,再到複雜的效果鏈結。 本主題介紹使用 CompositionBrush 繪圖的概念。

請注意,使用 XAML UWP 應用程式時,您可以選擇使用 XAML 筆刷CompositionBrush 繪製 UIElement。 一般而言,如果您的案例受到 XAML 筆刷支援,則選擇 XAML 筆刷會比較容易也更推薦使用。 例如,以動畫顯示按鈕的色彩、以影像改變文字或圖形的填滿。 另一方面,如果您要嘗試 XAML 筆刷不支援的項目,例如使用動畫遮罩繪製或動畫九網格延伸或效果鏈結,您可以使用 CompositionBrush 透過使用 XamlCompositionBrushBase 來繪製 UIElement。

使用視覺層時,必須使用 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 (Insider Preview SDK)
CompositionBackdropBrush 從應用程式取樣背景像素,或使用直接取自應用程式視窗後方桌面的像素,來繪製區域。 可當成另一個 CompositionBrush 的輸入使用,就像 CompositionEffectBrush Windows 10 版本 1607 (SDK 14393)

使用純色進行繪製

CompositionColorBrush 會使用純色來繪製區域。 有多種方式可以指定 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);

使用線性漸層進行繪製

CompositionLinearGradientBrush 使用線性漸層來繪製區域。 線性漸層是將一種或多種色彩沿著一條線 (也就是漸層軸) 混合色彩的方式。 您可以使用 GradientStop 物件來指定漸層中的色彩及其位置。

以下插圖和程式碼顯示使用紅色和黃色 2 個停駐點的 LinearGradientBrush 所繪製的 SpriteVisual。

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

使用放射狀漸層進行繪製

CompositionRadialGradientBrush 使用放射狀漸層來繪製區域。 放射狀漸層是將一種或多種色彩從橢圓形的中央開始,並結束於橢圓形半徑。 您可以使用 GradientStop 物件來定義漸層中的色彩及其位置。

以下插圖和程式碼顯示使用 2 個 GradientStops 的 RadialGradientBrush 所繪製的 SpriteVisual。

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 來繪製一個區域。 例如,CompositionSurfaceBrush 會運用 LoadedImageSurface API,使用影像轉譯到 ICompositionSurface 介面,可以用來繪製區域。

以下插圖和程式碼顯示運用 LoadedImageSurface 使用甘草的點陣圖轉譯到 ICompositionSurface 上所繪製的 SpriteVisual。 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 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 也可以用來繪製區域,它會運用 Win2D (或 D2D) 轉譯 ICompositionSurface,使用其中的像素進行繪製。

以下程式碼展示使用 Win2D 將文字轉譯到 ICompositionSurface,然後用以繪製的 SpriteVisual。 請注意,若要使用 Win2D,您必須將 Win2D NuGet 套件包含在專案中。

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

同樣地,CompositionSurfaceBrush 也可以用來繪製 SpriteVisual,它會運用 Win2D 交互操作,並使用 SwapChain 進行繪製。 此範例提供例子來展示如何使用 Win2D 搭配交換鏈繪製 SpriteVisual。

使用影片進行繪製

CompositionSurfaceBrush 也可以用來繪製區域,它會運用 MediaPlayer 類別載入的影片轉譯 ICompositionSurface,使用其中的像素進行繪製。

以下程式碼展示使用載入 ICompositionSurface 的影片所繪製的 SpriteVisual。

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

使用濾鏡效果進行繪製

CompositionEffectBrush 會使用 CompositionEffect 的輸出來繪製區域。 視覺層中的效果,可以視為套用至來源內容集合的可動畫濾鏡效果,例如色彩、漸層、影像、影片、交換鏈、UI 的區域或視覺效果樹狀結構。 來源內容通常會使用另一個 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 進行繪製

CompositionMaskBrush 會使用已套用不透明度遮罩的 CompositionBrush 來繪製區域。 不透明度遮罩的來源可以是 CompositionColorBrush、CompositionLinearGradientBrush、CompositionSurfaceBrush、CompositionEffectBrush 或 CompositionNineGridBrush 類型的任何 CompositionBrush。 不透明度遮罩必須指定為 CompositionSurfaceBrush。

以下插圖和程式碼顯示使用 CompositionMaskBrush 所繪製的 SpriteVisual。 遮罩的來源是 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 運用 NineGrid 延伸進行繪製

CompositionNineGridBrush 會運用九宮格思考法延伸 CompositionBrush 後,使用它來繪製區域。 九宮格思考法可讓您對 CompositionBrush 邊緣和角落進行延伸的方式,不同於其中心的延伸。 九宮格延伸的來源,可以是 CompositionColorBrush、CompositionSurfaceBrush 或 CompositionEffectBrush 類型的任何 CompositionBrush。

下列程式碼顯示以 CompositionNineGridBrush 繪製的 SpriteVisual。 遮罩的來源是 CompositionSurfaceBrush,其使用 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);

使用背景像素進行繪製

CompositionBackdropBrush 會使用區域後方的內容來繪製區域。 CompositionBackdropBrush 絕不會單獨使用,而是用來做為另一個 CompositionBrush 的輸入,例如做為 EffectBrush 的輸入。 舉例來說,藉由使用 CompositionBackdropBrush 做為模糊效果的輸入,您可以達成毛玻璃效果。

以下程式碼顯示小型視覺化樹狀結構,它使用 CompositionSurfaceBrush 並在影像上加入毛玻璃重疊,透過此法來建立影像。 將填滿 EffectBrush 的 SpriteVisual 放在影像上方,即可建立毛玻璃重疊。 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 會使用其他 CompositionBrushes 做為輸入。 例如,使用 SetSourceParameter 方法可用來將另一個 CompositionBrush 設定為 CompositionEffectBrush 的輸入。 下表概述所支援的 CompositionBrushes 組合。 請注意,使用不支援的組合將會擲回例外狀況。

Brush EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
CompositionColorBrush
CompositionLinear
GradientBrush
CompositionSurfaceBrush
CompositionEffectBrush
CompositionMaskBrush
CompositionNineGridBrush
CompositionBackdropBrush

使用 XAML 筆刷與 CompositionBrush

下表提供案例清單,以及當您在應用程式中繪製 UIElement 或 SpriteVisual 時,要指定使用 XAML 還是組合筆刷。

注意

如果針對 XAML UIElement 建議 CompositionBrush,則會假設 CompositionBrush 是使用 XamlCompositionBrushBase 封裝。

案例 XAML UIElement Composition SpriteVisual
使用單色來繪製區域 SolidColorBrush \(英文\) CompositionColorBrush
使用動畫色彩來繪製區域 SolidColorBrush \(英文\) CompositionColorBrush
使用靜態漸層來繪製區域 LinearGradientBrush \(英文\) CompositionLinearGradientBrush
使用動畫漸層停駐點來繪製區域 CompositionLinearGradientBrush CompositionLinearGradientBrush
使用影像來繪製區域 ImageBrush \(英文\) CompositionSurfaceBrush
使用網頁來繪製區域 WebViewBrush \(英文\) N/A
使用 NineGrid 延伸來繪製區域 Image 控制項 CompositionNineGridBrush
使用動畫的 NineGrid 延伸來繪製區域 CompositionNineGridBrush CompositionNineGridBrush
使用交換鏈來繪製區域 SwapChainPanel CompositionSurfaceBrush 含交換鏈交互操作
使用影片來繪製區域 MediaElement CompositionSurfaceBrush 含媒體交互操作
使用自訂 2D 繪圖來繪製區域 Win2D 的 CanvasControl CompositionSurfaceBrush 含 Win2D 交互操作
使用非動畫遮罩來繪製區域 使用 XAML 圖形來定義遮罩 CompositionMaskBrush
使用動畫遮罩來繪製區域 CompositionMaskBrush CompositionMaskBrush
使用動畫濾鏡效果來繪製區域 CompositionEffectBrush CompositionEffectBrush
使用套用至背景像素的效果來繪製區域 CompositionBackdropBrush CompositionBackdropBrush

使用 BeginDraw 和 EndDraw 組合原生 DirectX 和 Direct2D 交互操作

XAML 筆刷與 XamlCompositionBrushBase 交互操作