Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este tutorial apresenta alguns dos recursos básicos de desenho do Win2D. Você aprenderá a:
- Adicione Win2D a um projeto do Windows XAML em C#.
- Desenhe texto e geometria.
- Aplique efeitos de filtro.
- Anime seu conteúdo Win2D.
- Siga as práticas recomendadas do Win2D.
Configurar sua máquina de desenvolvimento
Certifique-se de configurar sua máquina com todas as ferramentas necessárias:
- Instalar o Visual Studio
- Inclua a UWP ou o SDK do Windows (dependendo das suas necessidades), 17763+
- Se estiver usando UWP, certifique-se de também habilitar modo de desenvolvedor
Criar um novo projeto Win2D
Siga as etapas no início rápido "Olá, Mundo!" do Win2D para criar um novo projeto usando o Win2D e para adicionar uma referência ao pacote NuGet do Win2D. Você pode usar a WinUI 3 (SDK de Aplicativo do Windows) ou a Plataforma Universal do Windows (UWP).
Adicionar um Win2D CanvasControl ao XAML do seu aplicativo
- Para usar o Win2D, você precisa de algum lugar para desenhar seus gráficos. Em um aplicativo XAML, a maneira mais simples de fazer isso é adicionar um CanvasControl à sua página XAML.
Antes de continuar, primeiro verifique se a opção Arquitetura do projeto está definida como x86
ou x64
e não como nem ou Any CPU
. Win2D é implementado em C++ e, portanto, os projetos que usam Win2D precisam ser direcionados para uma arquitetura de CPU específica.
Navegue até
MainPage.xaml
no seu projeto clicando duas vezes nele no Gerenciador de Soluções. Isso abrirá o arquivo. Por conveniência, você pode clicar duas vezes no botão XAML na guia Designer; Isso ocultará o Visual Designer e reservará todo o espaço para a Visualização de código.Antes de adicionar o controle, você primeiro precisa dizer ao XAML onde CanvasControl está definido. Para fazer isso, vá para a definição do elemento Page e adicione esta diretiva:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
. Seu XAML agora deve ter esta aparência:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Agora, adicione um novo
canvas:CanvasControl
elemento como filho ao elemento Grid raiz. Dê um nome ao controle — por exemplo, "canvas". Seu XAML agora deve ter esta aparência:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- Em seguida, defina um manipulador de eventos para o evento Draw .
O CanvasControl é acionado
Draw
sempre que seu aplicativo precisa desenhar ou redesenhar seu conteúdo. A maneira mais fácil é permitir que o Visual Studio AutoComplete o ajude. Na definição de CanvasControl , comece a digitar um novo atributo para o manipulador deDraw
eventos:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Observação
Depois de inserir o Draw="
, o Visual Studio deve exibir uma caixa solicitando que você permita que ele preencha automaticamente a definição correta para o manipulador de eventos. Pressione TAB para aceitar o manipulador de eventos padrão do Visual Studio. Isso também adicionará automaticamente um método manipulador de eventos formatado corretamente em seu code-behind ('MainPage.xaml.cs''). Não se preocupe se você não usou o Preenchimento Automático; Você pode adicionar manualmente o método manipulador de eventos na próxima etapa.
Desenhe seu primeiro texto no Win2D
Agora, vamos para o código C# por trás. Abra
MainPage.xaml.cs
no Gerenciador de Soluções.Na parte superior do arquivo C# estão várias definições de namespace. Adicione os seguintes namespaces:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- Em seguida, você verá o seguinte manipulador de eventos em branco que foi inserido pelo AutoComplete:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
(Se você não usou o Preenchimento Automático na etapa anterior, adicione este código agora.)
- O parâmetro CanvasDrawEventArgs expõe um membro, DrawingSession, que é do tipo CanvasDrawingSession. Esta classe fornece a maioria da funcionalidade básica de desenho no Win2D: ele tem métodos como CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage e o método que você precisa para desenhar texto, CanvasDrawingSession.DrawText.
Adicione o seguinte código ao método canvas_Draw
:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
O primeiro argumento, "Hello, World!"
, é a cadeia de caracteres que você deseja que o Win2D exiba. Os dois "100" dizem ao Win2D para deslocar este texto por 100 DIPs (pixels independentes do dispositivo) para a direita e para baixo. Finalmente, Colors.Black
define a cor do texto.
- Agora você está pronto para executar seu primeiro aplicativo Win2D. Pressione a tecla F5 para compilar e iniciar. Você deve ver uma janela vazia com "Olá, mundo!" em preto.
Descarte corretamente os recursos do Win2D
- Antes de continuar a desenhar outros tipos de conteúdo, primeiro você deve adicionar algum código para garantir que seu aplicativo evite vazamentos de memória. A maioria dos aplicativos Win2D escritos em uma linguagem .NET e usando um controle Win2D como CanvasControl precisa seguir as etapas abaixo. A rigor, seu aplicativo simples "Olá, mundo" não é afetado, mas essa é uma boa prática a ser seguida em geral.
Para obter mais informações, consulte Evitando vazamentos de memória.
Abra
MainPage.xaml
e localize o elemento XAML Page que contém seu CanvasControl. Deve ser o primeiro elemento no arquivo.Adicione um manipulador para o evento
Unloaded
. Seu XAML deve ter esta aparência:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Vá para
MainPage.xaml.cs
e localize o manipulador dePage_Unloaded
eventos. Adicione o seguinte código:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Se seu aplicativo contiver vários controles Win2D, você precisará repetir as etapas acima para cada página XAML que contém um controle Win2D. Atualmente, a tua aplicação tem apenas um único CanvasControl, por isso está tudo pronto.
Desenhar algumas formas
- É igualmente fácil adicionar geometria 2D à sua aplicação. Adicione o seguinte código ao final de
canvas_Draw
:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
Os argumentos para estes dois métodos são semelhantes a DrawText
. Um círculo é definido por um ponto central (125, 125), um raio (100) e uma cor (verde). Uma linha é definida por um início (0, 0), um fim (50, 200) e uma cor (Vermelho).
- Agora, pressione F5 para executar o aplicativo. Você deve ver "Olá, mundo!" junto com um círculo verde e linha vermelha.
Você pode estar se perguntando como controlar opções de desenho mais avançadas, como espessura de linha e traços, ou opções de preenchimento mais complexas, como o uso de pincéis. O Win2D fornece todas essas opções e muito mais, e facilita o uso quando você quiser. Todos os Draw(...)
métodos oferecem muitas sobrecargas que podem aceitar parâmetros adicionais, como CanvasTextFormat (família de fontes, tamanho, etc) e CanvasStrokeStyle (traços, pontos, endcaps, etc). Sinta-se à vontade para explorar a superfície da API para saber mais sobre essas opções.
Gerar parâmetros de desenho dinamicamente
- Agora, vamos adicionar alguma variedade desenhando um monte de formas e texto com cores aleatórias.
Adicione o seguinte código ao topo da sua MainPage
classe. Esta é uma funcionalidade auxiliar para gerar valores aleatórios que você usará ao desenhar:
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 seu
canvas_Draw
método para desenhar usando estes parâmetros aleatórios:
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 detalhar como DrawText
mudou.
"Hello, World!"
permanece o mesmo de antes. Os parâmetros de deslocamento x e y foram substituídos por um único System.Numerics.Vetor2 que é gerado pelo RndPosition
. Finalmente, em vez de usar uma cor predefinida, Color.FromArgb
permite definir uma cor usando valores A, R, G e B. A é alfa, ou o nível de opacidade; neste caso, deve ser sempre totalmente opaco (255).
DrawCircle
e DrawLine
funcionam de forma semelhante à DrawText
.
- Finalmente, envolva o seu código de desenho num loop de
for
. Você deve obter o seguinte 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()));
}
- Execute o aplicativo novamente. Você deve ver um monte de texto, linhas e círculos com posições e tamanhos aleatórios.
Aplicar um efeito de imagem ao seu conteúdo
Os efeitos de imagem, também conhecidos como efeitos de filtro, são transformações gráficas que são aplicadas aos dados de pixel. Saturação, rotação de tonalidade e desfoque gaussiano são alguns efeitos de imagem comuns. Os efeitos de imagem podem ser encadeados, produzindo uma aparência visual sofisticada para um esforço mínimo.
Você usa efeitos de imagem fornecendo uma imagem de origem (o conteúdo com o qual está começando), criando um efeito como GaussianBlurEffect, definindo propriedades como BlurAmount e, em seguida, desenhando a saída do efeito com DrawImage
.
Para aplicar um efeito de imagem ao texto e às formas, você precisa primeiro renderizar esse conteúdo em uma CanvasCommandList. Este objeto é utilizável como uma entrada para o seu efeito.
- Altere seu
canvas_Draw
método para usar o seguinte código:
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()));
}
}
Assim como você obtém um CanvasDrawingSession
a partir do CanvasDrawEventArgs
qual você pode desenhar, você pode criar um CanvasDrawingSession
a partir de um CanvasCommandList
. A única diferença é que quando você desenha para a sessão de desenho da lista de comandos (clds), você não está renderizando diretamente para o CanvasControl. Em vez disso, a lista de comandos é um objeto intermediário que armazena os resultados da renderização para uso posterior.
Você deve ter notado o bloco using
que envolve a sessão de desenho da lista de comandos. As sessões de desenho implementam IDisposable e devem ser descartadas quando você terminar a renderização (o using
bloco faz isso). O CanvasDrawingSession
que tu obténs do CanvasDrawEventArgs
é automaticamente fechado para ti, mas deves descartar todas as sessões de desenho que criaste explicitamente.
- Finalmente, defina o
GaussianBlurEffect
adicionando o seguinte código ao final docanvas_Draw
método:
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Execute o aplicativo novamente. Deverá ver as suas linhas, texto e círculos com uma aparência desfocada.
Anime seu aplicativo com CanvasAnimatedControl
. O Win2D dá-lhe a capacidade de atualizar e animar o seu conteúdo em tempo real, por exemplo, alterando o raio de desfocagem do desfoque gaussiano com cada fotograma. Para fazer isso, você usará CanvasAnimatedControl.
O CanvasControl é mais adequado para conteúdo gráfico principalmente estático - ele só gera o evento quando o Draw
conteúdo precisa ser atualizado ou redesenhado. Se tens conteúdo em constante mudança, deverias considerar usar CanvasAnimatedControl
em vez disso. Os dois controlos funcionam de forma muito semelhante, exceto que CanvasAnimatedControl
aciona o evento Draw
periodicamente; por defeito, ele é chamado 60 vezes por segundo.
- Para alternar para
CanvasAnimatedControl
, vá paraMainPage.xaml
, exclua a linha CanvasControl e substitua-a pelo seguinte XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Assim como no CanvasControl, deixe o AutoComplete criar o manipulador de Draw
eventos para você. Por padrão, o Visual Studio nomeará esse manipulador canvas_Draw_1
porque canvas_Draw
já existe, aqui, renomeamos o método canvas_AnimatedDraw
para deixar claro que esse é um evento diferente.
Além disso, você também está lidando com um novo evento, CreateResources. Mais uma vez, deixe o AutoComplete criar o manipulador.
Agora que seu aplicativo será redesenhado a 60 quadros por segundo, é mais eficiente criar seus recursos visuais Win2D uma vez e reutilizá-los a cada quadro. É ineficiente criar um CanvasCommandList
e desenhar 300 elementos nele 60 vezes por segundo quando o conteúdo permanece estático.
CreateResources
é um evento que é acionado somente quando o Win2D determina que você precisa recriar seus recursos visuais, como quando a página é carregada.
- Volte para
MainPage.xaml.cs
. Encontre o seucanvas_Draw
método que deve ter esta aparência:
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);
}
A grande maioria deste código de desenho existente não precisa ser executada com cada quadro: a lista de comandos contendo o texto, linhas e círculos permanece a mesma com cada quadro, e a única coisa que muda é o raio de desfoque. Portanto, você pode mover esse código "estático" para CreateResources
.
Para fazer isso, primeiro corte (CTRL+X) todo o conteúdo de canvas_Draw
, exceto a última linha (args.DrawingSession.DrawImage(blur);
). Agora pode eliminar o restante de canvas_Draw
, pois já não é necessário: lembre-se de que CanvasAnimatedControl
tem o seu próprio evento distinto Draw
.
- Encontre o método gerado
canvas_CreateResources
automaticamente:
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Cole (CTRL+V) o código cortado anteriormente neste método. Em seguida, mova a declaração de fora do corpo do GaussianBlurEffect
método para que a variável se torne um membro da classe MainPage. Seu código agora deve ter a seguinte aparência:
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
};
}
- Agora podes animar o desfoque gaussiano. Encontre o
canvas_DrawAnimated
método e adicione o seguinte código:
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);
}
Isto lê o tempo total decorrido fornecido por CanvasAnimatedDrawEventArgs e usa esses dados para calcular a quantidade de desfoque desejada; a função seno proporciona uma variação interessante ao longo do tempo. Finalmente, o GaussianBlurEffect
é renderizado.
- Execute o aplicativo para ver o conteúdo desfocado mudar ao longo do tempo.
Parabéns por concluir este tutorial de início rápido! Espero que você tenha visto como você pode usar o Win2D para criar uma cena visual rica e animada com apenas algumas linhas de código C# e XAML.
Windows developer