次の方法で共有


コンポジションのブラシ

WinUI アプリで画面に表示されるすべてのものが、ブラシによって描画されたために表示されます。 ブラシを使用すると、単純な純色から画像、描画、複雑なエフェクト チェーンまで、コンテンツを含むユーザー インターフェイス (UI) オブジェクトを描画できます。 このトピックでは、CompositionBrush を使用した描画の概念について説明します。

WinUI XAML アプリを使用する場合は、 XAML ブラシ または CompositionBrush を使用して UIElement を描画することを選択できます。 通常、シナリオが既にサポートされている場合は、XAML ブラシを選択する方が簡単です。 たとえば、ボタンの色をアニメーション化したり、テキストや図形の塗りつぶしを画像で変更したりします。 アニメーション化されたマスク、アニメーション化された 9 グリッド ストレッチ、効果チェーンなど、XAML ブラシでサポートされていないものが必要な場合は、CompositionBrush を使用して XamlCompositionBrushBase を使用して UIElement を描画できます。

ビジュアル レイヤーを操作する場合は、 SpriteVisual の領域を描画するために CompositionBrush を使用する必要があります。

前提条件

この概要では、「 ビジュアル レイヤーの概要」で説明されているように、基本的なコンポジション アプリケーションの構造を理解していることを前提としています。

CompositionBrush を使用したペイント

CompositionBrush は、その出力を含む領域を "塗りつぶします" 。 ブラシによって出力の種類が異なります。 一部のブラシは、単色で領域を塗りつぶし、他のブラシはグラデーション、画像、カスタム描画、または効果で塗りつぶします。 他のブラシの動作を変更する特殊なブラシもあります。 たとえば、不透明度マスクを使用して CompositionBrush で塗りつぶす領域を制御したり、9 グリッドを使用して領域を塗りつぶすときに CompositionBrush に適用されるストレッチを制御することができます。 CompositionBrush には、次のいずれかの種類を指定できます。

クラス 詳細情報
CompositionColorBrush 単色で領域を塗りつぶします。
CompositionSurfaceBrush ICompositionSurface の内容を使用して領域を塗りつぶします。
CompositionEffectBrush コンポジション効果の内容で領域を塗りつぶします。
CompositionMaskBrush CompositionBrush で不透明度マスクを使用してビジュアルを描写します
CompositionNineGridBrush NineGrid ストレッチを使用して CompositionBrush で領域を塗装します
CompositionLinearGradientBrush 線形グラデーションで領域を塗りつぶします
CompositionRadialGradientBrush 放射状グラデーションで領域を塗ります
CompositionBackdropBrush アプリケーションから背景ピクセルをサンプリングするか、デスクトップ上のアプリケーションのウィンドウのすぐ後ろにあるピクセルをサンプリングして領域を描画します。 CompositionEffectBrush などの別の CompositionBrush への入力として使用されます

単色で塗りつぶす

CompositionColorBrush は領域を単色で塗ります。 SolidColorBrush の色を指定するには、さまざまな方法があります。 たとえば、アルファ、赤、青、緑 (ARGB) チャネルを指定したり、 Colors クラスによって提供される定義済みの色のいずれかを使用したりできます。

次の図とコードは、黒い色のブラシで塗りつぶされ、0x9ACD32の色の値を持つ単色のブラシで塗りつぶされる四角形を作成する小さなビジュアル ツリーを示しています。

CompositionColorBrush

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

線形グラデーションで塗る

CompositionLinearGradientBrush は、線形グラデーションで領域を塗りつぶします。 線形グラデーションは、1 つの線 (グラデーション軸) に 2 つ以上の色をブレンドします。 GradientStop オブジェクトを使用して、グラデーションの色とその位置を指定します。

次の図とコードは、赤と黄色を使用し、2 つの停止位置を持つ LinearGradientBrush で塗りつぶされた SpriteVisual を示しています。

CompositionLinearGradientBrush

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 は放射状グラデーションで領域に色を塗ります。 放射状グラデーションは、楕円の中心から始まり、楕円の半径で終わるグラデーションと 2 つ以上の色をブレンドします。 GradientStop オブジェクトは、グラデーション内の色とその位置を定義するために使用されます。

次の図とコードは、RadialGradientBrush と 2 GradientStops で塗りつぶされた SpriteVisual を示しています。

CompositionRadialGradientBrush

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 を使用して、 LoadedImageSurface API を使用して ICompositionSurface にレンダリングされたイメージで領域を描画できます。

次の図とコードは、LoadedImageSurface を使用して ICompositionSurface にレンダリングされたリコリスのビットマップで描かれた SpriteVisual を示しています。 CompositionSurfaceBrush のプロパティを使用して、ビジュアルの境界内でビットマップを拡大および配置できます。

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 を使用して、Win2D (または D2D) を使用してレンダリングされた ICompositionSurface のピクセルで領域を描画することもできます。

次のコードは、Win2D を使用して ICompositionSurface にレンダリングされたテキスト ランで塗りつぶされた SpriteVisual を示しています。 WinUI で Win2D を使用するには、 プロジェクトに Microsoft.Graphics.Win2D NuGet パッケージ をインストールします。

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 を使用して、Win2D 相互運用機能を使用して SwapChain で SpriteVisual を描画することもできます。 このサンプル では、Win2D を使用して SpriteVisual をスワップチェーンで描画する方法の例を示します。

ビデオでペイントする

CompositionSurfaceBrush を使用して、MediaPlayer クラスを介して読み込まれたビデオを使用してレンダリングされた ICompositionSurface のピクセルで領域を描画することもできます。

次のコードは、ビデオを ICompositionSurface に読み込んでペイントした SpriteVisual を示しています。

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

フィルター効果を使用してペイントする

CompositionEffectBrushCompositionEffect の出力で領域を描きます。 ビジュアル レイヤーの効果は、色、グラデーション、画像、ビデオ、スワップチェーン、UI の領域、ビジュアルのツリーなどのソース コンテンツのコレクションに適用されるアニメーション化可能なフィルター効果と考えることができます。 通常、ソース コンテンツは別の CompositionBrush を使用して指定されます。

次の図とコードは、彩度低下フィルター効果が適用された猫の画像が描画された SpriteVisual を示しています。

CompositionEffectBrush

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 として指定する必要があります。

次の図とコードは、CompositionMaskBrush で塗りつぶされた SpriteVisual を示しています。 マスクのソースは CompositionLinearGradientBrush であり、円の画像をマスクとして使用して円のようにマスクされます。

CompositionMaskBrush

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

NineGrid ストレッチと CompositionBrush を用いたペイント

CompositionNineGridBrush は、9 グリッドメタファーを使用して引き伸ばした CompositionBrush で領域を描画します。 9 グリッドのメタファーを使用すると、CompositionBrush のエッジとコーナーを中心とは異なる方法で引き伸ばすことができます。 9 グリッド ストレッチのソースは、CompositionColorBrush、CompositionSurfaceBrush、または CompositionEffectBrush のいずれかの CompositionBrush で実行できます。

次のコードは、CompositionNineGridBrush で塗りつぶされた SpriteVisual を示しています。 マスクのソースは、Nine-Grid を使用してストレッチされる CompositionSurfaceBrush です。

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 は単独では使用されませんが、代わりに EffectBrush のような別の CompositionBrush への入力として使用されます。 たとえば、CompositionBackdropBrush をぼかし効果への入力として使用すると、フロストガラス効果を実現できます。

次のコードは、CompositionSurfaceBrush を使用してイメージを作成する小さなビジュアル ツリーと、イメージの上にフロストガラスオーバーレイを示しています。 フロストガラスオーバーレイは、画像の上に EffectBrush で満たされた SpriteVisual を配置することによって作成されます。 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を組み合わせること

多くの CompositionBrush では、他の CompositionBrush が入力として使用されます。 たとえば、SetSourceParameter メソッドを使用して、CompositionEffectBrush への入力として別の CompositionBrush を設定できます。 次の表は、CompositionBrushes でサポートされている組み合わせの概要を示しています。 サポートされていない組み合わせを使用すると、例外がスローされることに注意してください。

ブラシ EffectBrush.SetSourceParameter() MaskBrush.Mask マスクブラシ.ソース NineGridBrush.Source
CompositionColorBrush はい はい はい はい
CompositionLinear
GradientBrush
はい はい はい いいえ
CompositionSurfaceBrush はい はい はい はい
CompositionEffectBrush いいえ いいえ はい いいえ
CompositionMaskBrush いいえ いいえ いいえ いいえ
CompositionNineGridBrush はい はい はい いいえ
CompositionBackdropBrush はい いいえ いいえ いいえ

XAML ブラシと CompositionBrush の使用

次の表は、アプリケーションで UIElement または SpriteVisual を描画する際に、どのシナリオで XAML または Composition ブラシの使用が推奨されるかを示します。

XAML UIElement に CompositionBrush が推奨される場合、CompositionBrush は XamlCompositionBrushBase を使用してパッケージ化されていると見なされます。

シナリオ XAML UIElement Composition SpriteVisual
単色で領域を塗りつぶす SolidColorBrush CompositionColorBrush
アニメーションの色で領域を塗りつぶす SolidColorBrush CompositionColorBrush
静的なグラデーションを使用して領域を塗りつぶす LinearGradientBrush CompositionLinearGradientBrush
アニメーション化されたグラデーションストップを使用して領域を塗りつぶします。 CompositionLinearGradientBrush CompositionLinearGradientBrush
イメージを使用して領域を塗りつぶす Imagebrush CompositionSurfaceBrush
Webページでエリアを表示する WebView2 N/A
NineGrid ストレッチを使用して画像で領域を塗りつける イメージ コントロール CompositionNineGridBrush
アニメーション化された NineGrid ストレッチを使用して領域を描画する CompositionNineGridBrush CompositionNineGridBrush
スワップチェーンを使用して領域を塗りつぶす SwapChainPanel CompositionSurfaceBrush を用いたスワップチェイン相互運用
ビデオで領域を塗りつぶす MediaPlayerElement CompositionSurfaceBrush (メディア相互運用機能付き)
カスタム 2D 描画を使って領域を塗る Win2D からの CanvasControl CompositionSurfaceBrush と Win2D の相互運用機能
非アニメーションのマスクを使用して領域を塗りつぶす XAML 図形 を使用してマスクを定義する CompositionMaskBrush
アニメーションマスクで領域を塗りつぶす CompositionMaskBrush CompositionMaskBrush
アニメーション化されたフィルター効果を使用して領域を塗りつぶす CompositionEffectBrush CompositionEffectBrush
背景ピクセルに効果を適用して領域をペイントする CompositionBackdropBrush CompositionBackdropBrush

コンポジションネイティブ DirectX および Direct2D の相互運用を BeginDraw と EndDraw で組み合わせる

XamlCompositionBrushBase を使用した XAML ブラシ相互運用