Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial se presentan algunas de las funcionalidades básicas de dibujo de Win2D. Aprenderá a:
- Agregue Win2D a un proyecto de Windows XAML de C#.
- Dibujar texto y geometría.
- Aplicar efectos de filtro.
- Animar el contenido de Win2D.
- Siga los procedimientos recomendados de Win2D.
Configuración de la máquina de desarrollo
Asegúrese de configurar la máquina con todas las herramientas necesarias:
-
Instalación de Visual Studio
- Incluir UWP o Windows SDK (según sus necesidades), 17763+
- Si usa UWP, asegúrese también de habilitar el modo de desarrollador
Creación de un nuevo proyecto win2D
Siga los pasos del inicio rápido "Hello, World!" de Win2D para crear un nuevo proyecto mediante Win2D y agregar una referencia al paquete NuGet Win2D. Puedes usar WinUI 3 (Windows App SDK) o la Plataforma universal de Windows (UWP).
Agregar un CanvasControl win2D al XAML de la aplicación
- Para poder usar Win2D, necesitas algún lugar para dibujar tus gráficos. En una aplicación XAML, la manera más sencilla de hacerlo es agregar canvasControl a la página XAML.
Antes de continuar, asegúrese primero de que la opción Arquitectura del proyecto esté establecida en x86
o x64
y no en . Win2D se implementa en C++y, por lo tanto, los proyectos que usan Win2D deben tener como destino una arquitectura de CPU específica.
Vaya a
MainPage.xaml
en su proyecto en el Explorador de soluciones, haciendo doble clic en él. Se abrirá el archivo. Para mayor comodidad, puedes hacer doble clic en el botón XAML de la pestaña Diseñador; esto ocultará el diseñador visual y reservará todo el espacio para la vista de código.Antes de agregar el control, primero tienes que indicar a XAML dónde se define CanvasControl . Para ello, vaya a la definición del elemento Page y agregue esta directiva:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
. El XAML debería tener ahora un aspecto similar al siguiente:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Ahora, agregue un nuevo
canvas:CanvasControl
como elemento secundario al elemento Grid raíz. Asigne un nombre al control , por ejemplo, "canvas". El XAML debería tener ahora un aspecto similar al siguiente:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- A continuación, defina un controlador de eventos para el evento Draw .
CanvasControl genera
Draw
cada vez que la aplicación necesite dibujar o volver a dibujar su contenido. La manera más fácil es permitir que Visual Studio AutoComplete le ayude. En la definición canvasControl , comience a escribir un nuevo atributo para el controlador deDraw
eventos:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Nota:
Una vez que haya escrito en Draw="
, Visual Studio debería mostrar un cuadro pidiéndole que le permita rellenar automáticamente la definición correcta para el controlador de eventos. Presione TAB para aceptar el controlador de eventos predeterminado de Visual Studio. Esto también agregará automáticamente un método de controlador de eventos con formato correcto en el código subyacente ("MainPage.xaml.cs"). No se preocupe si no usó AutoCompletar; Puede agregar manualmente el método del controlador de eventos en el paso siguiente.
Dibujar el primer texto en Win2D
Ahora, vamos al código de C# subyacente. Abra
MainPage.xaml.cs
desde el Explorador de soluciones.En la parte superior del archivo de C# hay varias definiciones de espacio de nombres. Agregue los siguientes espacios de nombres:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- A continuación, debería ver el siguiente controlador de eventos en blanco que insertó AutoComplete:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
(Si no usó AutoCompletar en el paso anterior, agregue este código ahora).
- El parámetro CanvasDrawEventArgs expone un miembro, DrawingSession, que es del tipo CanvasDrawingSession. Esta clase proporciona la mayor parte de la funcionalidad básica de dibujo en Win2D: tiene métodos como CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage y el método que necesita para dibujar texto, CanvasDrawingSession.DrawText.
Agregue el código siguiente al método canvas_Draw
:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
El primer argumento, "Hello, World!"
, es la cadena que desea que Win2D muestre. Los dos "100" indican a Win2D que desfase este texto en 100 DIPs (píxeles independientes del dispositivo) hacia la derecha y hacia abajo. Por último, Colors.Black
define el color del texto.
- Ahora ya está listo para ejecutar la primera aplicación Win2D. Presione la tecla F5 para compilar e iniciar. Debería ver una ventana vacía con "Hola mundo!" en negro.
Eliminación correcta de recursos de Win2D
- Antes de continuar dibujando otros tipos de contenido, primero debes agregar código para asegurarte de que la aplicación evita pérdidas de memoria. La mayoría de las aplicaciones Win2D escritas en un lenguaje .NET y el uso de un control Win2D como CanvasControl deben seguir los pasos siguientes. Estrictamente hablando, la sencilla aplicación "Hola mundo" no se ve afectada, pero esta es una buena práctica para seguir en general.
Para obtener más información, vea Evitar fugas de memoria.
Abra
MainPage.xaml
y busque el elemento XAML Page que contiene su CanvasControl. Debe ser el primer elemento del archivo.Agregue un controlador para el evento
Unloaded
. El XAML debe tener este aspecto:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Vaya a
MainPage.xaml.cs
y busque el controlador dePage_Unloaded
eventos. Agregue el código siguiente:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Si la aplicación contiene varios controles Win2D, debes repetir los pasos anteriores para cada página XAML que contenga un control Win2D. Actualmente, la aplicación solo tiene un CanvasControl, así que ya está lista.
Dibujar algunas formas
- Es tan fácil agregar geometría 2D a la aplicación. Agregue el código siguiente al final de
canvas_Draw
:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
Los argumentos de estos dos métodos son similares a DrawText
. Un círculo se define mediante un punto central (125, 125), un radio (100) y un color (verde). Una línea se define por un principio (0, 0), un final (50, 200) y un color (Rojo).
- Ahora, presione F5 para ejecutar la aplicación. Debería ver "Hello, world!" junto con un círculo verde y una línea roja.
Es posible que se pregunte cómo controlar opciones de dibujo más avanzadas, como grosor de línea y guiones, o opciones de relleno más complejas, como el uso de pinceles. Win2D proporciona todas estas opciones y mucho más, y facilita su uso cuando quieras. Todos los Draw(...)
métodos ofrecen muchas sobrecargas que pueden aceptar parámetros adicionales, como CanvasTextFormat (familia de fuentes, tamaño, etc.) y CanvasStrokeStyle (guiones, puntos, finales, etc.). No dude en explorar la superficie de API para obtener más información sobre estas opciones.
Generación dinámica de parámetros de dibujo
- Ahora, vamos a agregar cierta variedad dibujando un montón de formas y texto con colores aleatorios.
Agregue el código siguiente a la parte superior de la MainPage
clase. Esta es la funcionalidad auxiliar para generar valores aleatorios que usará al dibujar:
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);
}
- Modifique el
canvas_Draw
método para dibujar mediante estos parámetros aleatorios:
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()));
}
Vamos a desglosar cómo DrawText
ha cambiado.
"Hello, World!"
se mantiene igual que antes. Los parámetros de desplazamiento x e y se han reemplazado por un único System.Numerics.Vector2 generado por RndPosition
. Por último, en lugar de usar un color predefinido, Color.FromArgb
permite definir un color mediante valores A, R, G y B. A es alfa, o el nivel de opacidad; en este caso, se necesita que sea totalmente opaco (255).
DrawCircle
y DrawLine
funcionan de forma similar a DrawText
.
- Por último, envuelva su código de dibujo en un bucle
for
. Debería terminar con el siguiente códigocanvas_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()));
}
- Vuelva a ejecutar la aplicación. Debería ver un montón de texto, líneas y círculos con posiciones y tamaños aleatorios.
Aplicar un efecto de imagen al contenido
Los efectos de imagen, también conocidos como efectos de filtro, son transformaciones gráficas que se aplican a los datos de píxeles. La saturación, la rotación de matiz y el desenfoque gaussiano son algunos efectos de imagen comunes. Los efectos de imagen se pueden encadenar, lo que produce una apariencia visual sofisticada para un esfuerzo mínimo.
Para usar efectos de imagen, proporcione una imagen de origen (el contenido con el que empieza), creando un efecto como GaussianBlurEffect, estableciendo propiedades como BlurAmount y, a continuación, dibujando la salida del efecto con DrawImage
.
Para aplicar un efecto de imagen al texto y las formas, primero debe representar ese contenido en canvasCommandList. Este objeto se puede usar como entrada para el efecto.
- Cambie el
canvas_Draw
método para usar el código siguiente:
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()));
}
}
Al igual que cómo se obtiene un CanvasDrawingSession
de CanvasDrawEventArgs
con el que se puede dibujar, puede crear un CanvasDrawingSession
a partir de un CanvasCommandList
. La única diferencia es que cuando se dibuja en la sesión de dibujo de la lista de comandos (clds), no se representa directamente en CanvasControl. En su lugar, la lista de comandos es un objeto intermedio que almacena los resultados de la representación para su uso posterior.
Es posible que haya observado el bloque using
que envuelve la sesión de dibujo de la lista de comandos. Las sesiones de dibujo implementan IDisposable y deben eliminarse cuando haya terminado de representarse (el using
bloque lo hace). El CanvasDrawingSession
que obtiene de CanvasDrawEventArgs
se cierra automáticamente, pero debe descartar las sesiones de dibujo que haya creado explícitamente.
- Por último, defina
GaussianBlurEffect
agregando el código siguiente al final delcanvas_Draw
método :
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Vuelva a ejecutar la aplicación. Debería ver las líneas, el texto y los círculos con una apariencia borrosa.
Animar la aplicación con CanvasAnimatedControl
. Win2D te ofrece la posibilidad de actualizar y animar tu contenido en tiempo real, por ejemplo cambiando el radio de desenfoque del desenfoque gaussiano con cada fotograma. Para ello, usará CanvasAnimatedControl.
CanvasControl es más adecuado para el contenido de gráficos estáticos principalmente: solo genera el Draw
evento cuando el contenido debe actualizarse o volver a dibujarse. Si ha cambiado continuamente el contenido, debe considerar la posibilidad de usar CanvasAnimatedControl
en su lugar. Los dos controles funcionan de forma muy similar, excepto que CanvasAnimatedControl
genera el evento Draw
de forma periódica; por defecto, se llama 60 veces por segundo.
- Para cambiar a
CanvasAnimatedControl
, vaya aMainPage.xaml
, elimine la línea CanvasControl y reemplácela por el código XAML siguiente:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Al igual que con CanvasControl, deje que AutoComplete cree el Draw
controlador de eventos automáticamente. De forma predeterminada, Visual Studio asignará un nombre a este controlador canvas_Draw_1
porque canvas_Draw
ya existe; aquí, hemos cambiado el nombre del método canvas_AnimatedDraw
para aclarar que se trata de un evento diferente.
Además, usted también está manejando un nuevo evento, CreateResources. Una vez más, deje que AutoComplete cree el controlador.
Ahora que la aplicación se volverá a dibujar a 60 fotogramas por segundo, es más eficaz crear los recursos visuales de Win2D una vez y reutilizarlos con cada fotograma. Es ineficaz crear CanvasCommandList
y dibujar 300 elementos en él 60 veces por segundo cuando el contenido permanece estático.
CreateResources
es un evento que se desencadena solo cuando Win2D determina que necesita volver a crear los recursos visuales, como cuando se carga la página.
- Vuelva a
MainPage.xaml.cs
. Busque el métodocanvas_Draw
que se vea así:
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 gran mayoría de este código de dibujo existente no necesita ejecutarse con cada fotograma: la lista de comandos que contiene el texto, las líneas y los círculos permanecen iguales con cada fotograma y lo único que cambia es el radio de desenfoque. Por lo tanto, puede mover este código "estático" a CreateResources
.
Para ello, corte primero (CTRL+X) todo el contenido de canvas_Draw
, excepto la última línea (args.DrawingSession.DrawImage(blur);
). Ahora puede eliminar el resto de canvas_Draw
, ya que ya no es necesario: recuerde que CanvasAnimatedControl
tiene su propio evento distinto Draw
.
- Busque el método
canvas_CreateResources
automáticamente generado.
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Pegue (CTRL+V) el código cortado previamente en este método. A continuación, mueva la declaración de GaussianBlurEffect
fuera del cuerpo del método para que la variable se convierta en miembro de la clase MainPage. El código debe tener un aspecto parecido al siguiente.
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
};
}
- Ahora puedes animar el desenfoque gaussiano. Busque el
canvas_DrawAnimated
método y agregue el código siguiente:
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);
}
Esto lee el tiempo total transcurrido proporcionado por CanvasAnimatedDrawEventArgs y lo usa para calcular la cantidad de desenfoque deseada; la función sine proporciona una variación interesante a lo largo del tiempo. Por último, se representa el GaussianBlurEffect
.
- Ejecute la aplicación para ver el cambio de contenido borroso a lo largo del tiempo.
Enhorabuena por completar este tutorial de inicio rápido. Esperamos que hayas visto cómo puedes usar Win2D para crear una escena visual enriquecida y animada con unas pocas líneas de código XAML y C#.