Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tutorial apresenta alguns dos recursos básicos de desenho do Win2D. Você aprenderá a:
- Adicione o Win2D a um projeto do Windows XAML em C#.
- Desenhar texto e geometria.
- Aplicar efeitos de filtro.
- Anime o conteúdo do Win2D.
- Siga as práticas recomendadas do Win2D.
Configurar seu computador de desenvolvimento
Configure seu computador com todas as ferramentas necessárias:
-
Instalar Visual Studio
- Incluir o SDK do UWP ou do Windows (dependendo de suas necessidades), 17763+
- Se estiver usando UWP, certifique-se de também habilitar o modo de desenvolvedor
Criar um novo projeto Win2D
Siga as etapas no início rápido do Win2D "Olá, Mundo!" para criar um novo projeto usando o Win2D e adicionar uma referência ao pacote NuGet Win2D. Você pode usar o WinUI 3 (SDK do Aplicativo do Windows) ou a UWP (Plataforma Universal do Windows).
Adicionar um Win2D CanvasControl ao XAML do aplicativo
- Para usar o Win2D, você precisa de um lugar para desenhar seus gráficos. Em um aplicativo XAML, a maneira mais simples de fazer isso é adicionar um CanvasControl à página XAML.
Antes de continuar, primeiro verifique se a opção Arquitetura do projeto está definida como x86
ou x64
e , não de a Any CPU
. O Win2D é implementado no C++e, portanto, os projetos que usam o Win2D precisam ser direcionados a uma arquitetura de CPU específica.
Navegue até
MainPage.xaml
em seu projeto clicando duas vezes nele no Gerenciador de Soluções. Isso abrirá o arquivo. Para conveniência, você pode clicar duas vezes no botão XAML na guia Designer; isso ocultará o designer visual e reservará todo o espaço para a exibição de código.Antes de adicionar o controle, primeiro você precisa informar 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, "tela". 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 .
CanvasControl aciona
Draw
sempre que seu aplicativo precisa desenhar ou redesenhar seu conteúdo. A maneira mais fácil é permitir que o Preenchimento Automático do Visual Studio ajude você. Na definição CanvasControl , comece a digitar um novo atributo para oDraw
manipulador de eventos:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Observação
Depois de ter entrado em Draw="
, o Visual Studio deverá abrir uma caixa solicitando que você permita que ela preencha automaticamente a definição certa 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 de 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 do manipulador de eventos na próxima etapa.
Desenhar seu primeiro texto no Win2D
Agora, vamos para o código C# atrá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ê deverá 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. Essa classe fornece a maior parte da funcionalidade básica de desenho no Win2D: ela tem métodos como CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage e o método necessário 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" indicam ao Win2D para deslocar esse texto em 100 DIPs (pixels independentes de dispositivo) para a direita e para baixo. Por fim, 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.
Descartar 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. Estritamente falando, seu aplicativo simples "Olá, mundo" não é afetado, mas essa é uma boa prática a seguir em geral.
Para obter mais informações, consulte Como evitar vazamentos de memória.
Abra
MainPage.xaml
e localize o elemento XAML da página que contém o CanvasControl. Ele 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 encontre o manipulador de eventosPage_Unloaded
. Adicione o seguinte código:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Se o aplicativo contiver vários controles Win2D, você precisará repetir as etapas acima para cada página XAML que contém um controle Win2D. No momento, seu aplicativo tem apenas um CanvasControl , portanto, você está pronto.
Desenhar algumas formas
- É tão fácil adicionar geometria 2D ao seu aplicativo. 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 esses 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 final (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ê deve estar se perguntando como controlar opções de desenho mais avançadas, como espessura e traços de linha, ou opções de preenchimento mais complexas, como usar pincéis. O Win2D fornece todas essas opções e muito mais e facilita o uso delas quando você quiser.
Draw(...)
Todos os métodos oferecem várias sobrecargas que podem aceitar parâmetros adicionais, como CanvasTextFormat (família de fontes, tamanho, etc.) e CanvasStrokeStyle (traços, pontos, terminações, etc.). Fique à vontade para explorar a superfície da API para saber mais sobre essas opções.
Gerar dinamicamente parâmetros de desenho
- Agora, vamos adicionar alguma variedade desenhando um monte de formas e texto com cores aleatórias.
Adicione o código a seguir à parte superior da classe MainPage
. Essa é a 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 analisar 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.Vector2 que é gerado por RndPosition
. Por fim, em vez de usar uma cor predefinida, Color.FromArgb
permite que você defina uma cor usando valores A, R, G e B. A é alfa ou o nível de opacidade; nesse caso, você sempre deseja totalmente opaco (255).
DrawCircle
e DrawLine
operam de forma semelhante a DrawText
.
- Por fim, embrulhe o código de desenho em um 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 aplicadas aos dados de pixel. Saturação, rotação de matiz e desfoque gaussiano são alguns efeitos comuns de imagem. Os efeitos de imagem podem ser encadeados, produzindo aparência visual sofisticada para esforço mínimo.
Use efeitos de imagem fornecendo uma imagem de origem (o conteúdo com o qual você está começando), criando um efeito como GaussianBlurEffect, definindo propriedades como BlurAmount e desenhando a saída do efeito com DrawImage
.
Para aplicar um efeito de imagem ao seu texto e formas, primeiro você precisa renderizar esse conteúdo em um CanvasCommandList. Esse objeto pode ser usado como entrada para 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 uma CanvasDrawingSession
de CanvasDrawEventArgs
com a qual você pode desenhar, você pode criar uma CanvasDrawingSession
de um CanvasCommandList
. A única diferença é que, quando você desenha para a sessão de desenho (clds) da lista de comandos, 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.
Talvez você tenha notado o bloco using
que encapsula a sessão de desenho da lista de comandos. As sessões de desenho implementam IDisposable e devem ser descartadas quando você terminar de renderizar (o using
bloco faz isso). O CanvasDrawingSession
obtido de CanvasDrawEventArgs
é fechado automaticamente para você, mas você deve descartar qualquer sessão de desenho que você criou explicitamente.
- Por fim, defina a
GaussianBlurEffect
adicionando o seguinte código ao final do métodocanvas_Draw
.
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Execute o aplicativo novamente. Você deve ver suas linhas, texto e círculos com uma aparência desfocada.
Animar seu aplicativo com CanvasAnimatedControl
. O Win2D permite atualizar e animar seu conteúdo em tempo real, por exemplo, alterando o raio do desfoque gaussiano a cada quadro. Para fazer isso, você usará CanvasAnimatedControl.
CanvasControl é mais adequado para conteúdo gráficos estáticos , ele só gera o Draw
evento quando seu conteúdo precisa ser atualizado ou redesenhado. Se você tiver conteúdo em constante mudança, considere usar CanvasAnimatedControl
ao invés. Os dois controles operam da mesma forma, exceto CanvasAnimatedControl
gera o Draw
evento periodicamente; por padrão, 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, permita que o AutoComplete crie o Draw
manipulador de 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á tratando um novo evento, CreateResources. Mais uma vez, permita que o AutoComplete crie 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
. Localize ocanvas_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 desse código de desenho existente não precisa ser executada com cada quadro: a lista de comandos que contém o texto, linhas e círculos permanece a mesma em 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 pela última linha (args.DrawingSession.DrawImage(blur);
). Agora você pode excluir o restante, canvas_Draw
pois ele não é mais necessário: lembre-se de que CanvasAnimatedControl
tem seu próprio evento distinto Draw
.
- Localize 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) seu código recortado anteriormente nesse 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. Agora, o código será parecido com o seguinte:
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 você pode animar o desfoque gaussiano. Localize 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);
}
Isso lê o tempo total decorrido fornecido por CanvasAnimatedDrawEventArgs e o utiliza para calcular a quantidade de desfoque desejada; a função seno proporciona uma variação interessante ao longo do tempo. Por fim, o GaussianBlurEffect
é renderizado.
- Execute o aplicativo para ver como o conteúdo desfocado muda ao longo do tempo.
Parabéns por concluir este tutorial de início rápido! Espero que você tenha visto como pode usar o Win2D para criar uma cena visual avançada e animada com apenas algumas linhas de código C# e XAML.
Windows developer