Compartir a través de


Compilar una aplicación Win2D sencilla

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:

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

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

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

  2. 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">
  1. 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>
  1. 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 de Draw 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

  1. Ahora, vamos al código de C# subyacente. Abra MainPage.xaml.cs desde el Explorador de soluciones.

  2. 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;
  1. 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).

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

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

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

  1. Abra MainPage.xaml y busque el elemento XAML Page que contiene su CanvasControl. Debe ser el primer elemento del archivo.

  2. 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">
  1. Vaya a MainPage.xaml.cs y busque el controlador de Page_Unloaded eventos. Agregue el código siguiente:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
    this.canvas.RemoveFromVisualTree();
    this.canvas = null;
}
  1. 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

  1. 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).

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

  1. 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);
}
  1. 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.

  1. Por último, envuelva su código de dibujo en un bucle for. Debería terminar con el siguiente código canvas_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()));
}
  1. 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.

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

  1. Por último, defina GaussianBlurEffect agregando el código siguiente al final del canvas_Draw método :
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
  1. 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.

  1. Para cambiar a CanvasAnimatedControl, vaya a MainPage.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.

  1. Vuelva a MainPage.xaml.cs. Busque el método canvas_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 .

  1. 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
    };
}
  1. 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.

  1. 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#.