Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione presenta alcune delle funzionalità di disegno di base di Win2D. Si apprenderà come:
- Aggiungere Win2D a un progetto Windows XAML C#.
- Disegnare testo e geometria.
- Applicare effetti di filtro.
- Anima il tuo contenuto Win2D.
- Seguire le procedure consigliate di Win2D.
Configurare il computer di sviluppo
Assicurarsi di configurare il computer con tutti gli strumenti necessari:
-
Installa Visual Studio
- Includere la piattaforma UWP o Windows SDK (a seconda delle esigenze), 17763+
- Se si usa UWP, assicurarsi di abilitare anche la modalità sviluppatore
Creare un nuovo progetto Win2D
Seguire i passaggi della guida introduttiva "Hello, World!" win2D per creare un nuovo progetto con Win2D e aggiungere un riferimento al pacchetto NuGet Win2D. Puoi usare WinUI 3 (Windows App SDK) o la piattaforma UWP (Universal Windows Platform).
Aggiungere un oggetto CanvasControl Win2D al codice XAML dell'app
- Per usare Win2D, è necessario un punto per disegnare la grafica. In un'app XAML, il modo più semplice per eseguire questa operazione consiste nell'aggiungere canvasControl alla pagina XAML.
Prima di continuare, assicurati che l'opzione Architettura del progetto sia impostata su x86
o x64
e su , non su a Any CPU
. Win2D viene implementato in C++, quindi i progetti che usano Win2D devono essere destinati a un'architettura di CPU specifica.
Navigare a
MainPage.xaml
nel progetto facendo doppio clic su di esso in Esplora Soluzioni. Verrà aperto il file. Per praticità, puoi fare doppio clic sul pulsante XAML nella scheda Progettazione; in questo modo verrà nascosta la finestra di progettazione visiva e verrà riservato tutto lo spazio per la visualizzazione codice.Prima di aggiungere il controllo, devi prima indicare a XAML dove è definito CanvasControl . A tale scopo, passare alla definizione dell'elemento Page e aggiungere questa direttiva:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
. Il codice XAML dovrebbe ora essere simile al seguente:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Aggiungere ora un nuovo
canvas:CanvasControl
elemento come elemento figlio all'elemento Grid radice. Assegna un nome al controllo, ad esempio "canvas". Il codice XAML dovrebbe ora essere simile al seguente:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- Definire quindi un gestore eventi per l'evento Draw .
CanvasControl genera
Draw
ogni volta che l'app deve disegnare o ridisegnare il contenuto. Il modo più semplice è farsi aiutare dal completamento automatico di Visual Studio. Nella definizione CanvasControl iniziare a digitare un nuovo attributo per ilDraw
gestore eventi:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Annotazioni
Dopo aver immesso il testo in Draw="
, Visual Studio dovrebbe visualizzare una finestra che chiede se si desidera completare automaticamente la definizione corretta per il gestore eventi. Premere TAB per accettare il gestore eventi predefinito di Visual Studio. Verrà aggiunto automaticamente anche un metodo del gestore eventi formattato correttamente nel code-behind ('MainPage.xaml.cs''). Non preoccuparti se non hai usato il completamento automatico; è possibile aggiungere manualmente il metodo del gestore eventi nel passaggio successivo.
Disegnare il primo testo in Win2D
A questo punto, passiamo al codice sottostante C#. Apri
MainPage.xaml.cs
da Esplora soluzioni.Nella parte superiore del file C# sono presenti varie definizioni di namespace. Aggiungere i namespace seguenti:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- Verrà quindi visualizzato il gestore eventi vuoto seguente che è stato inserito da AutoComplete:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
Se il completamento automatico non è stato usato nel passaggio precedente, aggiungere ora questo codice.
- Il parametro CanvasDrawEventArgs espone un membro DrawingSession, che corrisponde al tipo CanvasDrawingSession. Questa classe offre la maggior parte delle funzionalità di disegno di base in Win2D: include metodi come CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage e il metodo che è necessario disegnare testo, CanvasDrawingSession.DrawText.
Aggiungere al metodo canvas_Draw
il codice seguente:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
Il primo argomento, "Hello, World!"
, è la stringa che si vuole visualizzare da Win2D. I due "100" indicano a Win2D di sfalsare questo testo di 100 DIP (pixel indipendenti dal dispositivo) a destra e verso il basso. Infine, Colors.Black
definisce il colore del testo.
- Ora sei pronto per eseguire la tua prima app Win2D. Premere il tasto F5 per compilare e avviare. Dovrebbe essere visualizzata una finestra vuota con "Hello, world!" in nero.
Eliminare correttamente le risorse Win2D
- Prima di continuare a disegnare altri tipi di contenuto, devi prima aggiungere codice per assicurarti che l'app eviti perdite di memoria. La maggior parte delle applicazioni Win2D scritte in un linguaggio .NET e l'uso di un controllo Win2D come CanvasControl devono seguire la procedura seguente. In senso stretto, la tua semplice app "Hello, world" non è interessata, ma questa è una buona pratica da seguire in generale.
Per altre informazioni, vedere Evitare perdite di memoria.
Aprire
MainPage.xaml
e trovare l'elemento XAML Page che contiene il tuo CanvasControl. Deve essere il primo elemento del file.Aggiungere un gestore per l'evento
Unloaded
. Il codice XAML dovrebbe essere simile al seguente:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Vai a
MainPage.xaml.cs
e trova il gestore eventiPage_Unloaded
. Aggiungere il codice seguente:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Se la tua app contiene più controlli Win2D, devi ripetere i passaggi precedenti per ogni pagina XAML che contiene un controllo Win2D. Al momento, l'app ha solo un singolo CanvasControl, quindi hai finito.
Disegnare alcune forme
- È altrettanto semplice aggiungere geometria 2D all'app. Aggiungere il codice seguente alla fine di
canvas_Draw
:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
Gli argomenti di questi due metodi sono simili a DrawText
. Un cerchio è definito da un punto centrale (125, 125), un raggio (100) e un colore (verde). Una linea è definita da un inizio (0, 0), una fine (50, 200) e un colore (rosso).
- Premere F5 per eseguire l'app. Verrà visualizzato "Hello, world!" insieme a un cerchio verde e a una linea rossa.
Ci si potrebbe chiedere come controllare opzioni di disegno più avanzate, ad esempio spessore linea e trattini, o opzioni di riempimento più complesse come l'uso di pennelli. Win2D offre tutte queste opzioni e altro ancora e semplifica l'uso quando vuoi. Tutti i metodi di Draw(...)
offrono molti sovraccarichi che possono accettare parametri aggiuntivi come CanvasTextFormat (famiglia di caratteri, dimensioni, ecc.) e CanvasStrokeStyle (trattini, punti, terminazioni, ecc.). È possibile esplorare l'area API per altre informazioni su queste opzioni.
Generare dinamicamente parametri di disegno
- A questo punto, aggiungiamo un po' di varietà disegnando una serie di forme e testo con colori casuali.
Aggiungi il codice seguente all'inizio della classe MainPage
. Questa è la funzionalità helper per generare valori casuali che verranno usati durante il disegno:
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);
}
- Modificare il
canvas_Draw
metodo per disegnare usando questi parametri casuali:
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()));
}
Di seguito viene descritto come DrawText
è cambiato.
"Hello, World!"
rimane uguale a prima. I parametri di offset x e y sono stati sostituiti con un singolo oggetto System.Numerics.Vector2 generato da RndPosition
. Infine, invece di usare un colore predefinito, Color.FromArgb
consente di definire un colore usando i valori A, R, G e B. A è alfa o livello di opacità; in questo caso si dovrebbe avere opaco completo (255).
DrawCircle
e DrawLine
funzionano in modo analogo a DrawText
.
- Infine, racchiudi il codice di disegno in un ciclo
for
. Dovresti arrivare al seguente codicecanvas_Draw
:
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()));
}
- Eseguire di nuovo l'app. Dovrebbe essere visualizzato un intero gruppo di testo, linee e cerchi con posizioni e dimensioni casuali.
Applicare un effetto immagine al contenuto
Gli effetti immagine, noti anche come effetti filtro, sono trasformazioni grafiche applicate ai dati pixel. La saturazione, la rotazione delle tonalità e la sfocatura gaussiana sono alcuni effetti di immagine comuni. Gli effetti immagine possono essere concatenati, producendo un aspetto visivo sofisticato per un lavoro minimo.
Gli effetti immagine vengono usati fornendo un'immagine di origine (il contenuto da cui si parte), applicando un effetto come GaussianBlurEffect, impostando proprietà come BlurAmount e quindi disegnando l'output dell'effetto con DrawImage
.
Per applicare un effetto immagine al testo e alle forme, è necessario prima eseguire il rendering del contenuto in canvasCommandList. Questo oggetto è utilizzabile come input per il tuo effetto.
- Modificare il
canvas_Draw
metodo per usare il codice seguente:
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()));
}
}
Proprio come si ottiene un CanvasDrawingSession
oggetto da CanvasDrawEventArgs
cui è possibile disegnare, è possibile creare un oggetto CanvasDrawingSession
da un oggetto CanvasCommandList
. L'unica differenza è che quando si disegna nella sessione di disegno dell'elenco comandi (clds), non si esegue direttamente il rendering in CanvasControl. L'elenco dei comandi è invece un oggetto intermedio che archivia i risultati del rendering per un uso successivo.
Potresti aver notato il blocco using
che avvolge la sessione di disegno dell'elenco dei comandi. Le sessioni di disegno implementano IDisposable e devono essere eliminate al termine del rendering (il using
blocco esegue questa operazione). Il CanvasDrawingSession
ottenuto da CanvasDrawEventArgs
automaticamente viene chiuso automaticamente, ma è necessario eliminare tutte le sessioni di disegno create in modo esplicito.
- Infine, definire
GaussianBlurEffect
aggiungendo il codice seguente alla fine delcanvas_Draw
metodo :
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Eseguire di nuovo l'app. Dovresti vedere le righe, il testo e i cerchi con un aspetto sfocato.
Animare l'app con CanvasAnimatedControl
. Win2D ti offre la possibilità di aggiornare e animare il contenuto in tempo reale, ad esempio modificando il raggio di sfocatura del blur gaussiano con ogni fotogramma. A tale scopo, si userà CanvasAnimatedControl.
CanvasControl è particolarmente adatto per il contenuto grafico statico, ma genera solo l'evento Draw
quando il contenuto deve essere aggiornato o ridisegnato. Se il contenuto cambia continuamente, dovresti considerare di usare CanvasAnimatedControl
. I due controlli funzionano in modo molto simile, eccetto che CanvasAnimatedControl
genera l'evento Draw
a intervalli regolari; per impostazione predefinita viene chiamato sessanta volte al secondo.
- Per selezionare
CanvasAnimatedControl
, vai aMainPage.xaml
, elimina la riga CanvasControl e sostituiscila con il seguente codice XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Proprio come con CanvasControl, lascia che il completamento automatico crei il gestore eventi Draw
per te. Per impostazione predefinita, Visual Studio denomina questo gestore canvas_Draw_1
perché canvas_Draw
esiste già. In questo caso è stato rinominato il metodo canvas_AnimatedDraw
per chiarire che si tratta di un evento diverso.
Inoltre, si gestisce anche un nuovo evento, CreateResources. Ancora una volta, lasciare che il completamento automatico crei il gestore.
Ora che l'app verrà ridisegnata a 60 fotogrammi al secondo, è più efficiente creare le risorse visive Win2D una volta e riutilizzarle con ogni fotogramma. È inefficiente creare un oggetto CanvasCommandList
e disegnare 300 elementi in esso 60 volte al secondo quando il contenuto rimane statico.
CreateResources
è un evento generato solo quando Win2D determina che è necessario ricreare le risorse visive, ad esempio quando la pagina viene caricata.
- Passare nuovamente a
MainPage.xaml.cs
. Trova il tuo metodocanvas_Draw
, che dovrebbe apparire come segue:
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);
}
La maggior parte di questo codice di disegno esistente non deve essere eseguita con ogni fotogramma: l'elenco di comandi contenente il testo, le righe e i cerchi rimane invariato con ogni fotogramma e l'unica cosa che cambia è il raggio di sfocatura. Pertanto, è possibile spostare questo codice "statico" in CreateResources
.
A tale scopo, tagliare prima (CTRL+X) l'intero contenuto di canvas_Draw
, ad eccezione dell'ultima riga (args.DrawingSession.DrawImage(blur);
). È ora possibile eliminare il resto di canvas_Draw
perché non è più necessario: ricordare che CanvasAnimatedControl
ha un proprio evento distinto Draw
.
- Trovare il metodo generato
canvas_CreateResources
automaticamente:
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Incolla (CTRL+V) il codice che hai tagliato precedentemente in questo metodo. Spostare quindi la dichiarazione di GaussianBlurEffect
all'esterno del corpo del metodo in modo che la variabile diventi un membro della classe MainPage. Il codice dovrebbe ora essere simile al seguente:
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
};
}
- Ora puoi animare la sfocatura gaussiana. Trovare il
canvas_DrawAnimated
metodo e aggiungere il codice seguente:
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);
}
Questo rileva il tempo totale trascorso fornito da CanvasAnimatedDrawEventArgs e lo usa per calcolare la quantità di sfocatura desiderata; la funzione seno fornisce una variazione interessante nel corso del tempo. Infine, viene eseguito il rendering del GaussianBlurEffect
.
- Avvia l'app per vedere come il contenuto sfocato cambia nel tempo.
Congratulazioni per aver completato questa esercitazione introduttiva. Speriamo di aver visto come usare Win2D per creare una scena visiva ricca e animata con poche righe di codice C# e XAML.