Kuas komposisi

Semua yang terlihat di layar Anda dari aplikasi UWP terlihat karena dicat oleh Brush. Kuas memungkinkan Anda melukis objek antarmuka pengguna (UI) dengan konten mulai dari warna sederhana, solid hingga gambar atau gambar hingga rantai efek yang kompleks. Topik ini memperkenalkan konsep lukisan dengan CompositionBrush.

Catatan, saat bekerja dengan aplikasi XAML UWP, Anda dapat memilih untuk melukis UIElement dengan XAML Brush atau CompositionBrush. Biasanya, lebih mudah dan disarankan untuk memilih kuas XAML jika skenario Anda didukung oleh XAML Brush. Misalnya, menanimasikan warna tombol, mengubah isian teks atau bentuk dengan gambar. Di sisi lain, jika Anda mencoba melakukan sesuatu yang tidak didukung oleh kuas XAML seperti lukisan dengan topeng animasi atau peregangan sembilan kisi animasi atau rantai efek, Anda dapat menggunakan CompositionBrush untuk melukis UIElement melalui penggunaan XamlCompositionBrushBase.

Saat bekerja dengan lapisan Visual, CompositionBrush harus digunakan untuk mengecat area SpriteVisual.

Prasyarat

Gambaran umum ini mengasumsikan bahwa Anda terbiasa dengan struktur aplikasi Komposisi dasar, seperti yang dijelaskan dalam Gambaran umum lapisan visual.

Paint dengan CompositionBrush

KomposisiBrush "melukis" area dengan outputnya. Kuas yang berbeda memiliki berbagai jenis output. Beberapa kuas melukis area dengan warna solid, yang lain dengan gradien, gambar, gambar kustom, atau efek. Ada juga kuas khusus yang memodifikasi perilaku kuas lain. Misalnya, masker opasitas dapat digunakan untuk mengontrol area mana yang dicat oleh CompositionBrush, atau sembilan grid dapat digunakan untuk mengontrol peregangan yang diterapkan pada CompositionBrush saat melukis area. KomposisiBrush bisa dari salah satu jenis berikut:

Kelas Detail Diperkenalkan Di
CompositionColorBrush Mengecat area dengan warna solid Windows 10, versi 1511 (SDK 10586)
KomposisiSurfaceBrush Melukis area dengan isi ICompositionSurface Windows 10, versi 1511 (SDK 10586)
KomposisiEffectBrush Melukis area dengan isi efek komposisi Windows 10, versi 1511 (SDK 10586)
KomposisiMaskBrush Melukis visual dengan CompositionBrush dengan masker opasitas Windows 10, versi 1607 (SDK 14393)
KomposisiNineGridBrush Mengecat area dengan CompositionBrush menggunakan peregangan NineGrid Windows 10, versi 1607 (SDK 14393)
CompositionLinearGradientBrush Mengecat area dengan gradien linier Windows 10, versi 1709 (SDK 16299)
KomposisiRadialGradientBrush Mengecat area dengan gradien radial Windows 10, versi 1903 (Insider Preview SDK)
KomposisiBackdropBrush Mengecat area dengan mengambil sampel piksel latar belakang dari aplikasi atau piksel tepat di belakang jendela aplikasi di desktop. Digunakan sebagai input ke CompositionBrush lain seperti CompositionEffectBrush Windows 10, versi 1607 (SDK 14393)

Paint dengan warna solid

CompositionColorBrush melukis area dengan warna solid. Ada berbagai cara untuk menentukan warna SolidColorBrush. Misalnya, Anda dapat menentukan saluran alfa, merah, biru, dan hijau (ARGB) atau menggunakan salah satu warna yang telah ditentukan sebelumnya yang disediakan oleh kelas Warna .

Ilustrasi dan kode berikut menunjukkan pohon visual kecil untuk membuat persegi panjang yang dibelai dengan kuas warna hitam dan dicat dengan kuas warna solid yang memiliki nilai warna 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);

Paint dengan gradien linier

CompositionLinearGradientBrush melukis area dengan gradien linier. Gradien linier memadukan dua warna atau lebih di seluruh garis, sumbu gradien. Anda menggunakan objek GradientStop untuk menentukan warna dalam gradien dan posisinya.

Ilustrasi dan kode berikut menunjukkan SpriteVisual yang dilukis dengan LinearGradientBrush dengan 2 stop menggunakan warna merah dan kuning.

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

Paint dengan gradien radial

KomposisiRadialGradientBrush melukis area dengan gradien radial. Gradien radial memadukan dua warna atau lebih dengan gradien mulai dari tengah elips dan berakhir pada radius elips. Objek GradientStop digunakan untuk menentukan warna dan lokasinya dalam gradien.

Ilustrasi dan kode berikut menunjukkan SpriteVisual yang dilukis dengan RadialGradientBrush dengan 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);

Paint dengan gambar

CompositionSurfaceBrush melukis area dengan piksel yang dirender ke ICompositionSurface. Misalnya, CompositionSurfaceBrush dapat digunakan untuk melukis area dengan gambar yang dirender ke permukaan ICompositionSurface menggunakan LoadedImageSurface API.

Ilustrasi dan kode berikut menunjukkan SpriteVisual yang dilukis dengan bitmap licorice yang dirender ke ICompositionSurface menggunakan LoadedImageSurface. Sifat KomposisiSurfaceBrush dapat digunakan untuk meregangkan dan menyelaraskan bitmap dalam batas visual.

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

Paint dengan gambar kustom

CompositionSurfaceBrush juga dapat digunakan untuk melukis area dengan piksel dari ICompositionSurface yang dirender menggunakan Win2D (atau D2D).

Kode berikut menunjukkan SpriteVisual yang dicat dengan eksekusi teks yang dirender ke ICompositionSurface menggunakan Win2D. Catatan, untuk menggunakan Win2D, Anda perlu menyertakan paket Win2D NuGet ke dalam proyek Anda.

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

Demikian pula, CompositionSurfaceBrush juga dapat digunakan untuk melukis SpriteVisual dengan SwapChain menggunakan interop Win2D. Sampel ini memberikan contoh cara menggunakan Win2D untuk melukis SpriteVisual dengan swapchain.

Paint dengan video

CompositionSurfaceBrush juga dapat digunakan untuk melukis area dengan piksel dari ICompositionSurface yang dirender menggunakan video yang dimuat melalui kelas MediaPlayer.

Kode berikut menunjukkan SpriteVisual yang dilukis dengan video yang dimuat ke 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);

Paint dengan efek filter

KomposisiEffectBrush melukis area dengan output KomposisiEffect. Efek dalam Lapisan Visual mungkin dianggap sebagai efek filter yang dapat dianimasikan yang diterapkan pada kumpulan konten sumber seperti warna, gradien, gambar, video, swapchain, wilayah UI Anda, atau pohon Visual. Konten sumber biasanya ditentukan menggunakan CompositionBrush lain.

Ilustrasi dan kode berikut menunjukkan SpriteVisual yang dicat dengan gambar kucing yang memiliki efek filter desaturasi yang diterapkan.

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

Untuk informasi selengkapnya tentang membuat Efek menggunakan KomposisiBrushes lihat Efek di lapisan Visual

Paint dengan CompositionBrush dengan masker opasitas diterapkan

KomposisiMaskBrush melukis area dengan CompositionBrush dengan masker opasitas yang diterapkan padanya. Sumber masker opasitas dapat berupa KomposisiBrush jenis CompositionColorBrush, CompositionLinearGradientBrush, KomposisiSurfaceBrush, KomposisiEffectBrush, atau KomposisiNineGridBrush. Masker opasitas harus ditentukan sebagai KomposisiSurfaceBrush.

Ilustrasi dan kode berikut menunjukkan SpriteVisual yang dilukis dengan CompositionMaskBrush. Sumber masker adalah CompositionLinearGradientBrush yang diselubungi agar terlihat seperti lingkaran menggunakan gambar lingkaran sebagai masker.

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

Paint dengan CompositionBrush menggunakan peregangan NineGrid

CompositionNineGridBrush melukis area dengan CompositionBrush yang direntangkan menggunakan metafora sembilan kisi. Metafora sembilan kisi memungkinkan Anda untuk meregangkan tepi dan sudut KomposisiBrush secara berbeda dari pusatnya. Sumber peregangan sembilan kisi dapat dengan KomposisiBrush jenis CompositionColorBrush, KomposisiSurfaceBrush, atau KomposisiEffectBrush.

Kode berikut menunjukkan SpriteVisual yang dilukis dengan CompositionNineGridBrush. Sumber masker adalah CompositionSurfaceBrush yang direntangkan menggunakan 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);

Paint menggunakan Piksel Latar Belakang

KomposisiBackdropBrush melukis area dengan konten di belakang area tersebut. KomposisiBackdropBrush tidak pernah digunakan sendiri, tetapi sebaliknya digunakan sebagai input ke KomposisiBrush lain seperti EffectBrush. Misalnya, dengan menggunakan KomposisiBackdropBrush sebagai input ke efek Blur, Anda dapat mencapai efek kaca beku.

Kode berikut menunjukkan pohon visual kecil untuk membuat gambar menggunakan KomposisiSurfaceBrush dan overlay kaca beku di atas gambar. Overlay kaca beku dibuat dengan menempatkan SpriteVisual yang diisi dengan EffectBrush di atas gambar. EffectBrush menggunakan CompositionBackdropBrush sebagai input untuk efek kabur.

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

Menggabungkan KomposisiBrush

Sejumlah CompositionBrushes menggunakan CompositionBrushes lain sebagai input. Misalnya, menggunakan metode SetSourceParameter dapat digunakan untuk mengatur CompositionBrush lain sebagai input ke CompositionEffectBrush. Tabel di bawah ini menguraikan kombinasi komposisiBrush yang didukung. Perhatikan, bahwa menggunakan kombinasi yang tidak didukung akan memberikan pengecualian.

Sikat EffectBrush.SetSourceParameter() MaskBrush.Mask MaskBrush.Source NineGridBrush.Source
CompositionColorBrush YA YA YA YA
CompositionLinear
GradienBrush
YA YA YA TIDAK
KomposisiSurfaceBrush YA YA YA YA
KomposisiEffectBrush TIDAK TIDAK YA TIDAK
KomposisiMaskBrush TIDAK TIDAK TIDAK TIDAK
KomposisiNineGridBrush YA YA YA TIDAK
KomposisiBackdropBrush YA TIDAK TIDAK TIDAK

Menggunakan XAML Brush vs. CompositionBrush

Tabel berikut menyediakan daftar skenario dan apakah penggunaan kuas XAML atau Komposisi ditentukan saat melukis UIElement atau SpriteVisual di aplikasi Anda.

Catatan

Jika CompositionBrush disarankan untuk UIElement XAML, diasumsikan bahwa CompositionBrush dipaketkan menggunakan XamlCompositionBrushBase.

Skenario XAML UIElement Komposisi SpriteVisual
Paint area dengan warna solid SolidColorBrush CompositionColorBrush
Paint area dengan warna animasi SolidColorBrush CompositionColorBrush
Paint area dengan gradien statis LinearGradientBrush CompositionLinearGradientBrush
Paint area dengan perhentian gradien animasi CompositionLinearGradientBrush CompositionLinearGradientBrush
Paint area dengan gambar ImageBrush KomposisiSurfaceBrush
Paint area dengan halaman web WebViewBrush T/A
Paint area dengan gambar menggunakan peregangan NineGrid Kontrol Gambar KomposisiNineGridBrush
Paint area dengan animasi NineGrid stretch KomposisiNineGridBrush KomposisiNineGridBrush
Paint area dengan swapchain SwapChainPanel KomposisiSurfaceBrush w/ interop swapchain
Paint area dengan video MediaElement KomposisiSurfaceBrush dengan interop media
Paint area dengan gambar 2D kustom CanvasControl dari Win2D KomposisiSurfaceBrush w/ Win2D interop
Paint area dengan masker non-animasi Menggunakan bentuk XAML untuk menentukan masker KomposisiMaskBrush
Paint area dengan topeng animasi KomposisiMaskBrush KomposisiMaskBrush
Paint area dengan efek filter animasi KomposisiEffectBrush KomposisiEffectBrush
Paint area dengan efek yang diterapkan ke piksel latar belakang KomposisiBackdropBrush KomposisiBackdropBrush

Komposisi directx asli dan interop Direct2D dengan BeginDraw dan EndDraw

XAML brush interop dengan XamlCompositionBrushBase