Bagikan melalui


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 KomposisiBrush.

Perhatikan, saat bekerja dengan aplikasi XAML UWP, Anda dapat memilih untuk melukis UIElement dengan XAML Brush atau CompositionBrush. Biasanya, lebih mudah dan disarankan untuk memilih sikat XAML jika skenario Anda didukung oleh XAML Brush. Misalnya, menganimasikan warna tombol, mengubah isi teks atau bentuk dengan gambar. Di sisi lain, jika Anda mencoba melakukan sesuatu yang tidak didukung oleh sikat 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.

Cat dengan KomposisiBrush

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 kisi dapat digunakan untuk mengontrol peregangan yang diterapkan pada CompositionBrush saat mengecat area. KomposisiBrush bisa dari salah satu jenis berikut:

Kelas Detail Diperkenalkan Dalam
CompositionColorBrush Mengecat area dengan warna solid Windows 10, versi 1511 (SDK 10586)
KomposisiSurfaceBrush Mengecat 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 KomposisiBrush dengan masker opasitas Windows 10, versi 1607 (SDK 14393)
KomposisiNineGridBrush Mengecat area dengan CompositionBrush menggunakan peregangan NineGrid Windows 10, versi 1607 (SDK 14393)
KomposisiLinearGradientBrush Melukis area dengan gradien linier Windows 10, versi 1709 (SDK 16299)
KomposisiRadialGradientBrush Mengecat area dengan gradien radial Windows 10, versi 1903 (Insider Preview SDK)
KomposisiBackdropBrush Melukis area dengan mengambil sampel piksel latar belakang dari aplikasi atau piksel tepat di belakang jendela aplikasi di desktop. Digunakan sebagai input ke KomposisiBrush lain seperti KomposisiEffectBrush Windows 10, versi 1607 (SDK 14393)

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

Cat 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 dicat dengan LinearGradientBrush dengan 2 stop menggunakan warna merah dan kuning.

KomposisiLinearGradientBrush

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

Cat dengan gradien radial

KomposisiRadialGradientBrush melukis area dengan gradien radial. Gradien radial memadukan dua warna atau lebih dengan gradien mulai dari bagian 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.

KomposisiRadialGradientBrush

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

Melukis 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.

KomposisiSurfaceBrush

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

Cat dengan gambar kustom

KomposisiSurfaceBrush juga dapat digunakan untuk mengecat 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. Perhatikan, 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, KomposisiSurfaceBrush juga dapat digunakan untuk melukis SpriteVisual dengan SwapChain menggunakan interop Win2D. Sampel ini memberikan contoh cara menggunakan Win2D untuk melukis SpriteVisual dengan swapchain.

Melukis dengan video

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

Kode berikut menunjukkan SpriteVisual yang dicat 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);

Cat 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.

KomposisiEffectBrush

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 KomposisiBrush lihat Efek di Lapisan visual

Cat dengan KomposisiBrush dengan masker opasitas diterapkan

CompositionMaskBrush melukis area dengan KomposisiBrush 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 ditutupi agar terlihat seperti lingkaran menggunakan gambar lingkaran sebagai masker.

KomposisiMaskBrush

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

Cat dengan KomposisiBrush menggunakan peregangan NineGrid

KomposisiNineGridBrush melukis area dengan KomposisiBrush 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 oleh KomposisiBrush jenis KomposisiColorBrush, KomposisiSurfaceBrush, atau KomposisiEffectBrush.

Kode berikut menunjukkan SpriteVisual yang dilukis dengan KomposisiNineGridBrush. 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);

Cat menggunakan Piksel Latar Belakang

KomposisiBackdropBrush melukis area dengan konten di belakang area. 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 ke 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 KomposisiBrush menggunakan KomposisiBrush lain sebagai input. Misalnya, menggunakan metode SetSourceParameter dapat digunakan untuk mengatur KomposisiBrush lain sebagai input ke KomposisiEffectBrush. 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 Sikat XAML vs. KomposisiBrush

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

Catatan

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

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

Komposisi directx asli dan interop Direct2D dengan BeginDraw dan EndDraw

Interop sikat XAML dengan XamlCompositionBrushBase