Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве представлены некоторые основные возможности рисования Win2D. Вы узнаете, как:
- Добавьте Win2D в приложение WinUI (C#).
- Нарисовать текст и геометрию.
- Применение эффектов фильтра.
- Анимируйте содержимое Win2D.
- Следуйте рекомендациям Win2D.
Ссылка на пакет NuGet Win2D
- Создайте приложение WinUI и добавьте пакет Nuget Microsoft.Graphics.Win2D .
Добавьте Win2D CanvasControl в XAML приложения
- Чтобы использовать Win2D, вам нужно где-то нарисовать графику. В приложении XAML самый простой способ сделать это — добавить CanvasControl на страницу в XAML.
Прежде чем продолжить, сначала убедитесь, что параметр архитектуры проекта установлен на x86 или x64, и не на Any CPU. Win2D реализован в C++, поэтому проекты, использующие Win2D, должны быть ориентированы на определенную архитектуру ЦП.
Перейдите к
MainWindow.xamlв вашем проекте, дважды щелкнув на нем в обозревателе решений. Откроется файл. Для удобства можно дважды нажать кнопку XAML на вкладке конструктора; Это позволит скрыть визуальный конструктор и зарезервировать все пространство для представления кода.Перед добавлением элемента управления сначала необходимо указать XAML, где определен CanvasControl . Чтобы сделать это, перейдите к определению элемента Window и добавьте следующую директиву:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml". Теперь xaml должен выглядеть следующим образом:
<Window
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d">
- Теперь добавьте новый элемент
canvas:CanvasControlв качестве дочернего элемента в корневой элемент Grid . Присвойте элементу управления имя, например "canvas". Теперь xaml должен выглядеть следующим образом:
<Grid>
<canvas:CanvasControl x:Name="canvas"/>
</Grid>
- Затем определите обработчик событий для события Draw.
CanvasControl вызывает
Drawвсякий раз, когда приложению требуется рисование или перерисовка содержимого. Самый простой способ — позволить Visual Studio autoComplete помочь вам. В определении CanvasControl начните вводить новый атрибут для обработчикаDrawсобытий:
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" />
Рисование первого текста в Win2D
Теперь давайте перейдем к файлу кода C#. Откройте
MainWindow.xaml.csиз Solution Explorer.В верхней части файла C# находятся различные определения пространства имен. Добавьте следующие пространства имен:
using Windows.UI;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
- Затем вы увидите следующий пустой обработчик событий, который был вставлен автозавершением:
private void canvas_Draw(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender,
Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
{
}
(Если вы не использовали автозавершение на предыдущем шаге, добавьте этот код сейчас.)
- Параметр CanvasDrawEventArgs предоставляет элемент, DrawingSession, являющийся типом CanvasDrawingSession. Этот класс предоставляет большую часть основных функций рисования в Win2D: он имеет такие методы, как CanvasDrawingSession.DrawRectangle, CanvasDrawingSession.DrawImage и метод, который необходимо нарисовать текст, CanvasDrawingSession.DrawText.
Добавьте следующий код в метод canvas_Draw:
args.DrawingSession.DrawText("Hello, World!", 100, 100, Colors.Black);
Первый аргумент — это строка, "Hello, World!"которую требуется отобразить Win2D. Две "100" дают команду Win2D сдвигать этот текст на 100 ДИП вправо и вниз. Наконец, Colors.Black определяет цвет текста.
- Теперь вы готовы запустить свое первое приложение Win2D. Нажмите клавишу F5 для компиляции и запуска. Вы должны увидеть пустое окно с "Hello, world!" в черном.
Правильное удаление ресурсов Win2D
- Прежде чем продолжить рисование других типов содержимого, сначала следует добавить код, чтобы убедиться, что приложение избегает утечки памяти. Большинство приложений Win2D, написанных на языке .NET и используя элемент управления Win2D, например CanvasControl необходимо выполнить следующие действия. Строго говоря, на ваше простое приложение "Hello, world" это не влияет, но в целом следовать этой практике полезно.
Дополнительные сведения см. в разделе "Избегание утечки памяти".
Откройте
MainWindow.xamlи найдите элемент XAML, содержащий canvasControl. Он должен быть первым элементом в файле.Добавьте обработчик для события
Unloaded. Код XAML должен выглядеть следующим образом:
<Page
...
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
mc:Ignorable="d"
Unloaded="Page_Unloaded">
- Перейдите к
MainWindow.xaml.csи найдите обработчик событийPage_Unloaded. Добавьте следующий код:
void Page_Unloaded(object sender, RoutedEventArgs e)
{
this.canvas.RemoveFromVisualTree();
this.canvas = null;
}
- Если приложение содержит несколько элементов управления Win2D, необходимо повторить описанные выше действия для каждой страницы XAML, содержащей элемент управления Win2D. В настоящее время приложение имеет только один CanvasControl , поэтому все готово.
Рисование некоторых фигур
- Так же легко добавить 2D-геометрию в приложение. Добавьте следующий код в конец
canvas_Draw:
args.DrawingSession.DrawCircle(125, 125, 100, Colors.Green);
args.DrawingSession.DrawLine(0, 0, 50, 200, Colors.Red);
Аргументы этих двух методов похожи на DrawText. Круг определяется точкой центра (125, 125), радиусом (100) и цветом (зеленым). Строка определяется началом (0, 0), концом (50, 200) и цветом (красным).
- Теперь нажмите клавишу F5, чтобы запустить приложение. Вы должны увидеть "Привет, мир!" вместе с зеленым кругом и красной линией.
Возможно, вам интересно, как управлять более сложными параметрами рисования, такими как толщина линии и дефисы, или более сложные варианты заливки, такие как использование кистей. Win2D предоставляет все эти параметры и многое другое и упрощает их использование при необходимости. Все методы Draw(...) предлагают множество перегрузок, которые могут принимать дополнительные параметры, такие как CanvasTextFormat (семейство шрифтов, размер и т. д.) и CanvasStrokeStyle (dashes, dots, endcaps и т. д.). Не стесняйтесь исследовать интерфейс API, чтобы узнать больше об этих возможностях.
Динамическое создание параметров рисования
- Теперь добавим разнообразия, нарисовав множество фигур и текста со случайными цветами.
Добавьте следующий код в верхнюю часть MainWindow класса. Это вспомогательные функции для создания случайных значений, которые будут использоваться при рисовании:
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);
}
- Измените метод
canvas_Draw, чтобы рисовать, используя эти случайные параметры:
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()));
}
Давайте разберем, как DrawText изменилось.
"Hello, World!" остается таким же, как и раньше. Параметры смещения x и y были заменены одним элементом System.Numerics.Vector2 , созданным RndPosition. Наконец, вместо использования предопределенного цвета можно определить цвет Color.FromArgb с помощью значений A, R, G и B. A — альфа- или уровень непрозрачности; В этом случае всегда требуется полностью непрозрачный (255).
DrawCircle и DrawLine работает аналогично DrawText.
- Наконец, оберните код отрисовки в
forцикл. В конечном итоге вам потребуется следующий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()));
}
- Снова запустите приложение. Вы должны увидеть целый ряд текста, линий и кругов со случайными позициями и размерами.
Применение эффекта изображения к содержимому
Эффекты изображения, также известные как эффекты фильтра, — это графические преобразования, применяемые к данным пикселей. Насыщенность, вращение оттенка и гауссово размытие являются общими эффектами изображения. Эффекты изображения можно объединять, создавая изысканный визуальный эффект с минимальными усилиями.
Эффекты изображения используются путем предоставления исходного изображения (содержимого, с которым вы начинаете), создания эффекта, например GaussianBlurEffect, задания свойств, таких как BlurAmount, а затем рисование выходных данных эффекта с помощью DrawImage.
Чтобы применить эффект изображения к тексту и фигурам, необходимо сначала отобразить это содержимое в CanvasCommandList. Этот объект можно использовать как входные данные для вашего эффекта.
- Измените
canvas_Drawметод, чтобы использовать следующий код:
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()));
}
}
Как и при получении CanvasDrawingSession из CanvasDrawEventArgs, с помощью которых можно рисовать, можно создать CanvasDrawingSession из CanvasCommandList. Единственное различие заключается в том, что при рисовании в сеансе рисования списка команд (clds), вы не выполняете прямую отрисовку в CanvasControl. Вместо этого список команд — это промежуточный объект, в который хранятся результаты отрисовки для последующего использования.
Возможно, вы заметили блок using, который оборачивает сеанс рисования списка команд. Сеансы рисования реализуют IDisposable и должны быть удалены при завершении отрисовки ( using блок делает это).
CanvasDrawingSession, полученные от CanvasDrawEventArgs, автоматически закрываются для вас, но необходимо удалить все созданные сеансы рисования.
- Наконец, определите
GaussianBlurEffect, добавив следующий код в конецcanvas_Drawметода:
GaussianBlurEffect blur = new GaussianBlurEffect();
blur.Source = cl;
blur.BlurAmount = 10.0f;
args.DrawingSession.DrawImage(blur);
- Снова запустите приложение. Вы должны видеть линии, текст и круги размытыми.
Анимация приложения с помощью CanvasAnimatedControl
. Win2D позволяет обновлять и анимировать содержимое в режиме реального времени, например изменяя радиус гауссовского размытия с каждым кадром. Для этого вы будете использовать CanvasAnimatedControl.
CanvasControl лучше всего подходит для в основном статического графического содержимого. Оно вызывает Draw событие только в том случае, если содержимое должно быть обновлено или перерисовано. Если у вас постоянно меняющееся содержимое, вместо этого следует рассмотреть возможность использования CanvasAnimatedControl . Два элемента управления работают очень похоже, за исключением того, что CanvasAnimatedControl инициирует событие Draw с определённой периодичностью; по умолчанию это происходит 60 раз в секунду.
- Чтобы переключиться на
CanvasAnimatedControl, перейдите кMainPage.xaml, удалите строку CanvasControl и замените ее следующим кодом XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<canvas:CanvasAnimatedControl x:Name="canvas" Draw="canvas_DrawAnimated" CreateResources="canvas_CreateResources"/>
</Grid>
Как и в CanvasControl, пусть Автодополнение создаст Draw обработчик событий для вас. По умолчанию Visual Studio будет называть этот обработчик canvas_Draw_1, так как canvas_Draw уже существует; здесь мы переименовали метод canvas_AnimatedDraw, чтобы убедиться, что это другое событие.
Кроме того, вы также обрабатываете новое событие CreateResources. Еще раз дайте автодополнению создать обработчик.
Теперь, когда приложение будет перерисовывать по 60 кадров в секунду, более эффективно создавать визуальные ресурсы Win2D один раз и повторно использовать их с каждым кадром. При неизменном содержимом неэффективно создавать CanvasCommandList и отрисовывать в нем 300 элементов 60 раз в секунду.
CreateResources — это событие, которое запускается только в том случае, если Win2D определяет необходимость повторного создания визуальных ресурсов, например при загрузке страницы.
- Переключитесь назад на
MainPage.xaml.cs.canvas_DrawНайдите метод, который должен выглядеть следующим образом:
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);
}
Подавляющее большинство существующего кода рисования не нужно выполнять на каждом кадре: список команд, содержащий текст, линии и круги, остается неизменным на каждом кадре, и единственное, что изменяется, так это радиус размытия. Поэтому этот статический код можно переместить в CreateResources.
Чтобы сделать это, сначала вырежьте (CTRL+X) все содержимое canvas_Draw, кроме самой последней строки (args.DrawingSession.DrawImage(blur);). Теперь вы можете удалить оставшуюся часть canvas_Draw, так как она больше не нужна: вспомните, что CanvasAnimatedControl имеет собственное отдельное событие Draw.
- Найдите автоматически созданный
canvas_CreateResourcesметод:
private void canvas_CreateResources(
Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender,
Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{}
Вставьте (CTRL+V) ранее вырезанный код в этот метод. Затем переместите объявление GaussianBlurEffect вне текста метода, чтобы переменная стала членом класса MainPage. Теперь код должен выглядеть следующим образом:
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
};
}
- Теперь вы можете анимировать гауссово размытие.
canvas_DrawAnimatedНайдите метод и добавьте следующий код:
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);
}
Это считывает общее прошедшее время, указанное CanvasAnimatedDrawEventArgs, и использует это для вычисления требуемого количества размытия; функция синуса предоставляет интересный вариант с течением времени. Наконец, отрисовывается GaussianBlurEffect.
- Запустите приложение, чтобы увидеть размытое содержимое с течением времени.
Поздравляем с завершением этого краткого руководства по началу работы! Надеюсь, вы узнали, как можно использовать Win2D для создания богатой анимированной визуальной сцены с несколькими строками кода C# и XAML.
Windows developer