Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Lernprogramm werden einige der grundlegenden Zeichenfunktionen von Win2D vorgestellt. Hier erfahren Sie, wie Sie:
- Hinzufügen von Win2D zu einer WinUI -App (C#).
- Zeichnen sie Text und Geometrie.
- Anwenden von Filtereffekten.
- Animieren Sie Ihre Win2D-Inhalte.
- Befolgen Sie die bewährten Methoden von Win2D.
Verweisen Sie auf das Win2D NuGet-Paket
- Erstellen Sie eine neue WinUI-App, und fügen Sie das Nuget-Paket "Microsoft.Graphics.Win2D " hinzu.
Fügen Sie ein Win2D CanvasControl zu Ihrer App-XAML hinzu
- Um Win2D zu verwenden, müssen Sie einen Ort zum Zeichnen Ihrer Grafiken haben. In einer XAML-App besteht die einfachste Methode darin, Ihrer XAML-Seite ein CanvasControl hinzuzufügen.
Bevor Sie fortfahren, stellen Sie zunächst sicher, dass die Architekturoption auf x86 oder x64 und nicht auf Any CPU festgelegt ist. Win2D wird in C++ implementiert, und daher müssen Projekte, die Win2D verwenden, auf eine bestimmte CPU-Architektur ausgerichtet sein.
Navigieren Sie zu
MainWindow.xamlin Ihrem project, indem Sie in Solution Explorer darauf doppelklicken. Dadurch wird die Datei geöffnet. Aus Gründen der Einfachheit können Sie auf die XAML-Schaltfläche auf der Registerkarte "Designer" doppelklicken. Dadurch wird der visuelle Designer ausgeblendet und der gesamte Platz für die Codeansicht reserviert.Bevor Sie das Steuerelement hinzufügen, müssen Sie zuerst XAML mitteilen, wo CanvasControl definiert ist. Gehen Sie zur Definition des Window-Elements und fügen Sie diese Direktive hinzu:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml". Ihr XAML sollte jetzt wie folgt aussehen:
<Window
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Fügen Sie nun dem
canvas:CanvasControlein neues als untergeordnetes Element hinzu. Geben Sie dem Steuerelement einen Namen, z. B. "canvas". Ihr XAML sollte jetzt wie folgt aussehen:
<Grid>
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- Definieren Sie als Nächstes einen Ereignishandler für das ereignis Draw.
CanvasControl löst
Drawaus, wenn Ihre App ihren Inhalt zeichnen oder neu zeichnen muss. Der einfachste Weg ist, sich von Visual Studio IntelliSense helfen zu lassen. Beginnen Sie in der CanvasControl-Definition mit der Eingabe eines neuen Attributs für denDrawEreignishandler:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Zeichnen des ersten Texts in Win2D
Jetzt gehen wir zum C#-Code-Behind. Öffnen Sie
MainWindow.xaml.csaus Solution Explorer.Oben in der C#-Datei befinden sich verschiedene Namespacedefinitionen. Fügen Sie die folgenden Namespaces hinzu:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- Als Nächstes sollte der folgende leere Ereignishandler angezeigt werden, der von Auto-Complete eingefügt wurde.
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
(Wenn Sie "Autovervollständigen" im vorherigen Schritt nicht verwendet haben, fügen Sie diesen Code jetzt hinzu.)
- Der Parameter CanvasDrawEventArgs macht ein Element verfügbarDrawingSession vom Typ CanvasDrawingSession. Diese Klasse bietet die meisten grundlegenden Zeichenfunktionen in Win2D: Sie verfügt über Methoden wie CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage und die Methode, die Sie zum Zeichnen von Text, CanvasDrawingSession.DrawText benötigen.
Fügen Sie der canvas_Draw-Methode folgenden Code hinzu:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
Das erste Argument ist die Zeichenfolge, "Hello, World!"die Win2D anzeigen soll. Die beiden Zahlen "100" weisen Win2D an, diesen Text um 100 DIPs (geräteunabhängige Pixel) nach rechts und unten zu verschieben.
Colors.Black Definiert schließlich die Farbe des Texts.
- Jetzt können Sie Ihre erste Win2D-App ausführen. Drücken Sie F5, um zu kompilieren und zu starten. Sie sollten ein leeres Fenster mit "Hallo, Welt!" in Schwarz sehen.
Ordnungsgemäßes Löschen von Win2D-Ressourcen
- Bevor Sie weiter andere Arten von Inhalten zeichnen, sollten Sie zuerst Code hinzufügen, um sicherzustellen, dass Ihre App Speicherverluste vermeidet. Die meisten Win2D-Anwendungen, die in einer .NET-Sprache geschrieben wurden und ein Win2D-Steuerelement, wie CanvasControl, verwenden, müssen die folgenden Schritte ausführen. Streng genommen ist Ihre einfache "Hello, world"-App nicht betroffen, aber dies ist eine gute Praxis, die allgemein zu befolgen ist.
Weitere Informationen finden Sie unter Vermeiden von Speicherlecks.
Öffnen Sie
MainWindow.xamlund suchen Sie das XAML-Element, das Ihr CanvasControl enthält. Es sollte das erste Element in der Datei sein.Fügen Sie einen Handler für das
Unloaded-Ereignis hinzu. Ihr XAML sollte wie folgt aussehen:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Wechseln Sie zu
MainWindow.xaml.csund suchen Sie den Ereignishandler vonPage_Unloaded. Fügen Sie den folgenden Code hinzu:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Wenn Ihre App mehrere Win2D-Steuerelemente enthält, müssen Sie die obigen Schritte für jede XAML-Seite wiederholen, die ein Win2D-Steuerelement enthält. Ihre App verfügt derzeit nur über ein einzelnes CanvasControl-Element , sodass Sie alle fertig sind.
Zeichne einige Formen
- Es ist genauso einfach, Ihrer App 2D-Geometrie hinzuzufügen. Fügen Sie den folgenden Code an das Ende der
canvas_Drawhinzu:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
Die Argumente für diese beiden Methoden ähneln DrawText. Ein Kreis wird durch einen Mittelpunkt (125, 125), einen Radius (100) und eine Farbe (Grün) definiert. Eine Linie wird durch einen Anfang (0, 0), ein Ende (50, 200) und eine Farbe (Rot) definiert.
- Drücken Sie nun F5, um die App auszuführen. Sie sollten "Hallo, Welt!" sowie einen grünen Kreis und eine rote Linie sehen.
Möglicherweise fragen Sie sich, wie Sie erweiterte Zeichnungsoptionen wie Linienstärke und Striche oder komplexere Fülloptionen wie die Verwendung von Pinseln steuern können. Win2D bietet alle diese Optionen und vieles mehr und erleichtert ihnen die Verwendung bei Bedarf. Alle Draw(...)-Methoden bieten viele Überladungen, die zusätzliche Parameter wie CanvasTextFormat (Schriftartfamilie, Größe usw.) und CanvasStrokeStyle (Striche, Punkte, Endcaps usw.) akzeptieren können. Sie können die API-Oberfläche erkunden, um mehr über diese Optionen zu erfahren.
Dynamisches Generieren von Zeichnungsparametern
- Jetzt fügen wir eine Gewisse Vielfalt hinzu, indem wir eine Reihe von Formen und Text mit zufälligen Farben zeichnen.
Fügen Sie den folgenden Code am Anfang der MainWindow Klasse hinzu. Diese ist eine Hilfsfunktion zum Generieren von Zufallswerten, die Sie beim Zeichnen verwenden werden.
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);
}
- Ändern Sie Ihre
canvas_Draw-Methode, um mit diesen zufälligen Parametern zu zeichnen.
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()));
}
Lassen Sie uns aufschlüsseln, wie DrawText sich geändert hat.
"Hello, World!" bleibt unverändert wie zuvor. Die x- und y-Offsetparameter wurden durch ein einzelnes System.Numerics.Vector2 ersetzt, das von RndPosition erzeugt wird. Schließlich können Sie anstelle einer vordefinierten Farbe Color.FromArgb eine Farbe mithilfe von A-, R-, G- und B-Werten definieren. A ist Alpha oder die Deckkraftstufe; in diesem Fall sollte es immer vollständig undurchsichtig sein (255).
DrawCircle und DrawLine funktionieren ähnlich wie DrawText.
- Schließen Sie schließlich den Zeichnungscode in einem
forloop um. Sie sollten den folgendencanvas_Draw-Code erhalten:
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()));
}
- Führen Sie die App erneut aus. Sie sollten jede Menge Text, Linien und Kreise mit zufälligen Positionen und Größen sehen.
Anwenden eines Bildeffekts auf Ihre Inhalte
Bildeffekte, auch als Filtereffekte bezeichnet, sind grafische Transformationen, die auf Pixeldaten angewendet werden. Sättigung, Farbtonrotation und Gaußscher Weichzeichner sind einige häufige Bildeffekte. Bildeffekte können miteinander verkettet werden, wodurch ein anspruchsvolles visuelles Erscheinungsbild für minimalen Aufwand entsteht.
Sie verwenden Bildeffekte, indem Sie ein Quellbild (den Inhalt, mit dem Sie beginnen), einen Effekt wie GausianBlurEffect bereitstellen, Eigenschaften wie BlurAmount festlegen und dann die Ausgabe des Effekts mit DrawImage zeichnen.
Um einen Bildeffekt auf Text und Formen anzuwenden, müssen Sie diesen Inhalt zuerst in einem CanvasCommandList rendern. Dieses Objekt kann als Eingabe für Ihren Effekt verwendet werden.
- Ändern Sie Ihre Methode
canvas_Drawso, dass sie den folgenden Code verwendet:
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()));
}
}
Genau wie Sie ein CanvasDrawingSession aus CanvasDrawEventArgs erhalten, mit dem Sie zeichnen können, können Sie ein CanvasDrawingSession aus einem CanvasCommandList erstellen. Der einzige Unterschied besteht darin, dass Sie beim Zeichnen in die Zeichnungssitzung der Befehlsliste (clds) nicht direkt auf CanvasControl rendern. Stattdessen ist die Befehlsliste ein Zwischenobjekt, das die Ergebnisse des Renderns für die spätere Verwendung speichert.
Möglicherweise haben Sie den using Block bemerkt, der die Zeichnungssitzung der Befehlsliste umschließt. Zeichnungssitzungen implementieren IDisposable und müssen freigegeben werden, wenn Sie mit dem Rendern fertig sind (der using Block übernimmt dies). Die CanvasDrawingSession, die Sie von CanvasDrawEventArgs erhalten, wird automatisch geschlossen; Sie müssen jedoch alle Zeichnungssitzungen löschen, die Sie selbst erstellt haben.
- Definieren Sie schließlich die
GaussianBlurEffect, indem Sie am Ende dercanvas_Draw-Methode den folgenden Code hinzufügen:
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Führen Sie die App erneut aus. Sie sollten Ihre Zeilen, Text und Kreise mit einer verschwommenen Darstellung sehen.
Animieren Sie Ihre App mit CanvasAnimatedControl
. Win2D bietet Ihnen die Möglichkeit, Ihre Inhalte in Echtzeit zu aktualisieren und zu animieren, z. B. durch Ändern des Unschärferadius des Gaußschen Weichzeichners in jedem Frame. Dazu verwenden Sie CanvasAnimatedControl.
CanvasControl eignet sich am besten für meist statische Grafikinhalte – es löst nur das Draw Ereignis aus, wenn Ihre Inhalte aktualisiert oder neu gezeichnet werden müssen. Wenn Sie Inhalte ständig ändern, sollten Sie stattdessen die Verwendung von CanvasAnimatedControl in Betracht ziehen. Die beiden Steuerelemente funktionieren sehr ähnlich, außer dass CanvasAnimatedControl regelmäßig das Draw-Ereignis auslöst; standardmäßig geschieht dies 60 Mal pro Sekunde.
- Um zu
CanvasAnimatedControlzu wechseln, gehen Sie zuMainPage.xaml, löschen Sie die Zeile CanvasControl, und ersetzen Sie sie durch den folgenden XAML-Code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Lassen Sie CanvasControl wie bei AutoVervollständigen den Draw Ereignishandler für Sie erstellen. Standardmäßig benennt Visual Studio diesen Handler canvas_Draw_1, da canvas_Draw bereits vorhanden ist. Hier haben wir die Methode canvas_AnimatedDraw umbenannt, um deutlich zu machen, dass dies ein anderes Ereignis ist.
Darüber hinaus behandeln Sie auch ein neues Ereignis, CreateResources. Lassen Sie AutoComplete erneut den Handler erstellen.
Da Ihre App jetzt mit 60 Frames pro Sekunde neu gezeichnet wird, ist es effizienter, Ihre visuellen Win2D-Ressourcen einmal zu erstellen und mit jedem Frame wiederzuverwenden. Es ist ineffizient, ein CanvasCommandList zu erstellen und 300 Elemente darin 60 Mal pro Sekunde zu zeichnen, wenn der Inhalt statisch bleibt.
CreateResources ist ein Ereignis, das nur ausgelöst wird, wenn Win2D bestimmt, dass Sie ihre visuellen Ressourcen neu erstellen müssen, z. B. wenn die Seite geladen wird.
- Wechseln Sie zurück zu
MainPage.xaml.cs. Suchen Sie Ihrecanvas_DrawMethode, die wie folgt aussehen soll:
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);
}
Der Großteil dieses vorhandenen Zeichen-Codes muss nicht in jedem Frame ausgeführt werden: Die Befehlsliste, die den Text, die Zeilen und Kreise enthält, bleibt in jedem Frame gleich, und das einzige, was sich ändert, ist der Unschärferadius. Daher können Sie diesen "statischen" Code in CreateResources verschieben.
Schneiden Sie dazu den gesamten Inhalt von canvas_Draw aus (STRG+X), mit Ausnahme der letzten Zeile (args.DrawingSession.DrawImage(blur);). Sie können nun den Rest von canvas_Draw löschen, da er nicht mehr benötigt wird: Denken Sie daran, dass CanvasAnimatedControl über ein eigenes Draw-Ereignis verfügt.
- Suchen Sie die automatisch generierte
canvas_CreateResources-Methode:
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Fügen Sie Ihren zuvor ausgeschnittenen Code in diese Methode ein. (STRG+V) Verschieben Sie als Nächstes die Deklaration außerhalb des GaussianBlurEffect Methodentexts, damit die Variable ein Element der MainPage-Klasse wird. Ihr Code sollte nun wie folgt aussehen:
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
};
}
- Jetzt können Sie den gaussischen Weichzeichner animieren. Suchen Sie die
canvas_DrawAnimated-Methode, und fügen Sie den folgenden Code hinzu:
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);
}
Dadurch wird die gesamte verstrichene Zeit gelesen, die von CanvasAnimatedDrawEventArgs bereitgestellt wird, und verwendet diese, um die gewünschte Weichzeichnungsmenge zu berechnen; die Sinusfunktion bietet im Laufe der Zeit eine interessante Variation. Abschließend wird die GaussianBlurEffect gerendert.
- Führen Sie die App aus, um zu sehen, wie sich der verschwommene Inhalt im Laufe der Zeit verändert.
Herzlichen Glückwunsch zum Abschluss dieses Schnellstart-Lernprogramms! Hoffentlich haben Sie gesehen, wie Sie Win2D verwenden können, um eine umfangreiche, animierte visuelle Szene mit nur wenigen Zeilen C# und XAML-Code zu erstellen.
Windows developer