Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze zelfstudie maakt u kennis met enkele van de basistekeningsmogelijkheden van Win2D. U leert het volgende:
- Win2D toevoegen aan een WinUI-app (C#).
- Teken tekst en geometrie.
- Filtereffecten toepassen.
- Animeer uw Win2D-inhoud.
- Volg best practices voor Win2D.
Verwijzen naar het Win2D NuGet-pakket
- Maak een nieuwe WinUI-app en voeg het Nuget-pakket Microsoft.Graphics.Win2D toe.
Een Win2D CanvasControl toevoegen aan de XAML van uw app
- Als u Win2D wilt gebruiken, moet u ergens uw afbeeldingen tekenen. De eenvoudigste manier om dit te doen in een XAML-app is om een CanvasControl toe te voegen aan uw XAML-pagina.
Voordat u doorgaat, moet u eerst controleren of de optie Architectuur van de project is ingesteld op x86 of x64 en not op Any CPU. Win2D wordt geïmplementeerd in C++, en daarom moeten projecten die gebruikmaken van Win2D worden gericht op een specifieke CPU-architectuur.
Navigeer naar
MainWindow.xamlin uw project door erop te dubbelklikken in Solution Explorer. Hiermee opent u het bestand. Voor het gemak kunt u dubbelklikken op de knop XAML op het tabblad Designer; Hiermee wordt de visualontwerper verborgen en wordt alle ruimte voor de codeweergave gereserveerd.Voordat u het besturingselement toevoegt, moet u eerst XAML vertellen waar CanvasControl is gedefinieerd. Om dit te doen, gaat u naar de definitie van het element Window en voegt u deze richtlijn toe:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml". Uw XAML moet er nu als volgt uitzien:
<Window
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Voeg nu een nieuw
canvas:CanvasControltoe als onderliggend element aan het root Grid-element. Geef het besturingselement een naam, bijvoorbeeld 'canvas'. Uw XAML moet er nu als volgt uitzien:
<Grid>
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- Definieer vervolgens een gebeurtenis-handler voor de gebeurtenis Draw.
CanvasControl roept
Drawop telkens wanneer uw app de inhoud moet tekenen of opnieuw moet tekenen. De eenvoudigste manier is om Visual Studio AutoAanvullen u te laten helpen. Begin in de CanvasControl-definitie een nieuw kenmerk te typen voor deDrawgebeurtenis-handler:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Uw eerste tekst tekenen in Win2D
Nu gaan we naar de C#-code op de achtergrond. Open
MainWindow.xaml.csvanuit Solution Explorer.Bovenaan het C#-bestand bevinden zich verschillende naamruimtedefinities. Voeg de volgende naamruimten toe:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- Vervolgens ziet u de volgende lege gebeurtenis-handler die is ingevoegd door Automatisch aanvullen:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
(Als u autoaanvullen niet hebt gebruikt in de vorige stap, voegt u deze code nu toe.)
- Met de parameter CanvasDrawEventArgs wordt een lid DrawingSession weergegeven. Dit is van het type CanvasDrawingSession. Deze klasse biedt de meeste basisfunctionaliteit voor tekenen in Win2D: het heeft methoden zoals CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage en de methode die u nodig hebt om tekst te tekenen, CanvasDrawingSession.DrawText.
Voeg de volgende code toe aan de methode canvas_Draw:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
Het eerste argument, "Hello, World!", is de tekenreeks die win2D moet weergeven. De twee "100"s vertellen Win2D om deze tekst te compenseren door 100 DIPs (apparaatonafhankelijke pixels) rechts en omlaag. Ten slotte definieert Colors.Black de kleur van de tekst.
- Nu bent u klaar om uw eerste Win2D-app uit te voeren. Druk op de F5-toets om te compileren en te starten. U zou een leeg venster moeten zien met 'Hallo, wereld!' in het zwart.
De Win2D-resources op de juiste manier verwijderen
- Voordat u verdergaat met het tekenen van andere soorten inhoud, moet u eerst wat code toevoegen om ervoor te zorgen dat uw app geheugenlekken voorkomt. De meeste Win2D-toepassingen die zijn geschreven in een .NET taal en een Win2D-besturingselement gebruiken, zoals CanvasControl moeten de onderstaande stappen volgen. Strikt genomen wordt uw eenvoudige "Hallo wereld"-app niet beïnvloed, maar dit is een goede gewoonte om in het algemeen te volgen.
Zie Geheugenlekken voorkomenvoor meer informatie.
Open
MainWindow.xamlhet XAML-element dat uw CanvasControl bevat en zoek het. Dit moet het eerste element in het bestand zijn.Voeg een handler toe voor de
Unloadedgebeurtenis. Uw XAML moet er als volgt uitzien:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Ga naar
MainWindow.xaml.csen zoek dePage_Unloadedeventafhandelaar. Voeg de volgende code toe:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Als uw app meerdere Win2D-besturingselementen bevat, moet u de bovenstaande stappen herhalen voor elke XAML-pagina die een Win2D-besturingselement bevat. Uw app heeft momenteel slechts één CanvasControl , zodat u klaar bent.
Enkele vormen tekenen
- Het is net zo eenvoudig om 2D-geometrie aan uw app toe te voegen. Voeg de volgende code toe aan het einde van
canvas_Draw:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
De argumenten voor deze twee methoden zijn vergelijkbaar met DrawText. Een cirkel wordt gedefinieerd door een middelpunt (125, 125), een straal (100) en een kleur (groen). Een lijn wordt gedefinieerd door een begin (0, 0), een eind (50, 200) en een kleur (rood).
- Druk nu op F5 om de app uit te voeren. U ziet 'Hallo, wereld!', samen met een groene cirkel en rode lijn.
U vraagt zich misschien af hoe u meer geavanceerde tekenopties kunt beheren, zoals lijndikte en streepjes, of complexere opvulopties, zoals het gebruik van borstels. Win2D biedt al deze opties en meer en maakt het gemakkelijk om ze te gebruiken wanneer u wilt. Alle Draw(...) methoden bieden veel overbelastingen die aanvullende parameters kunnen accepteren, zoals CanvasTextFormat (lettertypefamilie, grootte, enzovoort) en CanvasStrokeStyle (streepjes, stippen, eindkapjes, enzovoort). U kunt de API-surface verkennen voor meer informatie over deze opties.
Tekenparameters dynamisch genereren
- Laten we nu een aantal verschillende vormen en tekst met gerandomiseerde kleuren tekenen.
Voeg de volgende code toe aan het begin van uw MainWindow-klasse. Dit is helperfunctionaliteit voor het genereren van willekeurige waarden die u gaat gebruiken bij het tekenen:
Random rnd = new Random();
private Vector2 RndPosition()
{
double x = rnd.NextDouble() * 500f;
double y = rnd.NextDouble() * 500f;
return new Vector2((float)x, (float)y);
}
private float RndRadius()
{
return (float)rnd.NextDouble() * 150f;
}
private byte RndByte()
{
return (byte)rnd.Next(256);
}
- Wijzig uw
canvas_Drawmethode om te tekenen met behulp van deze willekeurige parameters:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
args.DrawingSession.DrawText("Hello, World!", RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
args.DrawingSession.DrawCircle(RndPosition(), RndRadius(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
args.DrawingSession.DrawLine(RndPosition(), RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
}
Laten we eens bekijken hoe DrawText is gewijzigd.
"Hello, World!" blijft hetzelfde als voorheen. De x- en y-offsetparameters zijn vervangen door één System.Numerics.Vector2 die wordt gegenereerd door RndPosition. Ten slotte kunt u, in plaats van een vooraf gedefinieerde kleur te gebruiken, Color.FromArgb een kleur definiëren met behulp van A-, R-, G- en B-waarden. A is alfa of het dekkingsniveau; in dit geval wilt u altijd volledig ondoorzichtig (255).
DrawCircle en DrawLine werken op dezelfde manier als DrawText.
- Ten slotte verpakt u de tekencode in een
forloop. Je zou moeten eindigen met de volgendecanvas_Draw-code.
for (int i = 0; i < 100; i++)
{
args.DrawingSession.DrawText("Hello, World!", RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
args.DrawingSession.DrawCircle(RndPosition(), RndRadius(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
args.DrawingSession.DrawLine(RndPosition(), RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
}
- Voer de app opnieuw uit. U ziet een heleboel tekst, lijnen en cirkels met willekeurige posities en grootten.
Een afbeeldingseffect toepassen op uw inhoud
Afbeeldingseffecten, ook wel filtereffecten genoemd, zijn grafische transformaties die worden toegepast op pixelgegevens. Verzadiging, tintrotatie en Gaussiaans vervagen zijn enkele veelvoorkomende afbeeldingseffecten. Afbeeldingseffecten kunnen worden gecombineerd, wat zorgt voor een geavanceerd visueel uiterlijk met minimale inspanning.
U gebruikt afbeeldingseffecten door een bronafbeelding op te geven (de inhoud waarmee u begint), waarbij u een effect maakt, zoals GaussianBlurEffect, eigenschappen zoals BlurAmount en vervolgens de uitvoer van het effect tekenen met DrawImage.
Als u een afbeeldingseffect wilt toepassen op uw tekst en vormen, moet u die inhoud eerst weergeven in een CanvasCommandList. Dit object kan worden gebruikt als invoer voor uw effect.
- Wijzig uw
canvas_Drawmethode om de volgende code te gebruiken:
CanvasCommandList cl = new CanvasCommandList(sender);
using (CanvasDrawingSession clds = cl.CreateDrawingSession())
{
for (int i = 0; i < 100; i++)
{
clds.DrawText("Hello, World!", RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawCircle(RndPosition(), RndRadius(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawLine(RndPosition(), RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
}
}
Net zoals hoe u een CanvasDrawingSession verkrijgt van CanvasDrawEventArgs waarmee u kunt tekenen, kunt u een CanvasDrawingSession maken op basis van een CanvasCommandList. Het enige verschil is dat wanneer u naar de tekensessie (clds) van de opdrachtlijst tekent, u niet rechtstreeks naar de CanvasControl rendert. In plaats daarvan is de opdrachtlijst een tussenliggend object waarin de resultaten van rendering worden opgeslagen voor later gebruik.
Mogelijk heb je het using blok gezien dat de tekensessie van de opdrachtlijst omvat. Tekensessies implementeren IDisposable en moeten worden verwijderd wanneer u klaar bent met renderen (het using blok doet dit). De CanvasDrawingSession die u van CanvasDrawEventArgs verkrijgt, wordt automatisch voor u gesloten, maar u moet tekensessies verwijderen die u expliciet hebt gemaakt.
- Definieer ten slotte de
GaussianBlurEffectdoor de volgende code toe te voegen aan het einde van de methodecanvas_Draw:
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Voer de app opnieuw uit. U zou uw lijnen, tekst en cirkels met een wazig uiterlijk moeten zien.
Animatie toevoegen aan uw app met CanvasAnimatedControl
. Win2D biedt u de mogelijkheid om uw inhoud in realtime bij te werken en animeren, bijvoorbeeld door de vervagende straal van de Gaussiische vervaging met elk frame te wijzigen. Om dit te doen, gebruikt u CanvasAnimatedControl.
CanvasControl is het meest geschikt voor voornamelijk statische grafische inhoud. Hiermee wordt alleen de Draw gebeurtenis gegenereerd wanneer uw inhoud moet worden bijgewerkt of opnieuw moet worden getekend. Als u voortdurend veranderende inhoud hebt, kunt u beter CanvasAnimatedControl gebruiken. De twee besturingselementen werken op dezelfde manier, behalve CanvasAnimatedControl de Draw-gebeurtenis periodiek verhoogt; deze wordt standaard 60 keer per seconde genoemd.
- Als u wilt overschakelen naar
CanvasAnimatedControl, gaat u naarMainPage.xaml, verwijdert u de regel met CanvasControl en vervangt u deze door de volgende XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Net als bij CanvasControl, laat AutoComplete de Draw gebeurtenishandler voor u maken. Standaard geeft Visual Studio deze handler de naam canvas_Draw_1 omdat canvas_Draw al bestaat. Hier hebben we de naam van de methode canvas_AnimatedDraw gewijzigd om duidelijk te maken dat dit een andere gebeurtenis is.
Daarnaast verwerkt u ook een nieuwe gebeurtenis, CreateResources. Laat AutoAanvullen opnieuw de handler maken.
Nu uw app opnieuw wordt getekend met 60 frames per seconde, is het efficiënter om uw Win2D-visualresources eenmaal te maken en opnieuw te gebruiken met elk frame. Het is inefficiënt om een CanvasCommandList te maken en 300 elementen er 60 keer per seconde in te trekken wanneer de inhoud statisch blijft.
CreateResources is een gebeurtenis die alleen wordt geactiveerd wanneer Win2D bepaalt dat u uw visuele resources opnieuw moet maken, bijvoorbeeld wanneer de pagina wordt geladen.
- Ga terug naar
MainPage.xaml.cs. Zoek uwcanvas_Drawmethode die er als volgt uit moet zien:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
CanvasCommandList cl = new CanvasCommandList(sender);
using (CanvasDrawingSession clds = cl.CreateDrawingSession())
{
for (int i = 0; i < 100; i++)
{
clds.DrawText("Hello, World!", RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawCircle(RndPosition(), RndRadius(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawLine(RndPosition(), RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
}
}
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
}
De overgrote meerderheid van deze bestaande tekencode hoeft niet te worden uitgevoerd met elk frame: de opdrachtlijst met de tekst, regels en cirkels blijft hetzelfde met elk frame en het enige wat verandert, is de vervagende straal. Daarom kunt u deze 'statische' code verplaatsen naar CreateResources.
Om dit te doen, knip (CTRL+X) eerst de volledige inhoud van canvas_Draw, met uitzondering van de laatste regel (args.DrawingSession.DrawImage(blur);). U kunt nu de rest van canvas_Draw verwijderen omdat deze niet meer nodig is: onthoud dat CanvasAnimatedControl een eigen afzonderlijke Draw gebeurtenis heeft.
- Zoek de automatisch gegenereerde
canvas_CreateResourcesmethode:
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Plak uw eerder geknipte code (Ctrl+V) in deze methode. Verplaats vervolgens de declaratie van GaussianBlurEffect buiten de hoofdtekst van de methode, zodat de variabele lid wordt van de klasse MainPage. Uw code moet er nu als volgt uitzien:
GaussianBlurEffect blur;
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
CanvasCommandList cl = new CanvasCommandList(sender);
using (CanvasDrawingSession clds = cl.CreateDrawingSession())
{
for (int i = 0; i < 100; i++)
{
clds.DrawText("Hello, World!", RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawCircle(RndPosition(), RndRadius(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
clds.DrawLine(RndPosition(), RndPosition(), Color.FromArgb(255, RndByte(), RndByte(), RndByte()));
}
}
blur = new GaussianBlurEffect()
{
Source = cl,
BlurAmount = 10.0f
};
}
- Nu kun je de Gaussiische vervaging animeren. Zoek de methode
canvas_DrawAnimateden voeg de volgende code toe:
private void canvas_DrawAnimated(
Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args)
{
float radius = (float)(1 + Math.Sin(args.Timing.TotalTime.TotalSeconds)) * 10f;
blur.BlurAmount = radius;
args.DrawingSession.DrawImage(blur);
}
Hiermee wordt de totale verstreken tijd gelezen die is opgegeven door CanvasAnimatedDrawEventArgs en wordt dit gebruikt om de gewenste hoeveelheid vervagen te berekenen; de sinusfunctie biedt een interessante variatie in de loop van de tijd. Ten slotte wordt de GaussianBlurEffect weergegeven.
- Start de app om de wazige inhoud in de loop van de tijd te zien veranderen.
Gefeliciteerd met het voltooien van deze quickstart-handleiding! Hopelijk hebt u gezien hoe u Win2D kunt gebruiken om een rijke, geanimeerde visuele scène te maken met slechts een paar regels C# en XAML-code.
Windows developer