Рисование графических объектов

Browse sample. Обзор примера

Графики многоплатформенного пользовательского интерфейса приложений .NET (.NET MAUI) в Microsoft.Maui.Graphics пространстве имен позволяют рисовать графические объекты на холсте, который определяется как ICanvas объект.

Элемент управления .NET MAUI GraphicsView предоставляет доступ к ICanvas объекту, для которого можно задать свойства и методы, вызываемые для рисования графических объектов. Дополнительные сведения о графическом представлении GraphicsViewсм. в разделе "Графика".

Примечание.

Многие графические объекты имеют Draw и методы, например DrawRectangleFillRectangle.Fill Draw Метод рисует контур фигуры, которая не заполнена. Fill Метод рисует контур фигуры, а также заполняет его.

Графические объекты рисуются на основе устройства независимой ICanvas от устройства единицы, распознаваемой каждой платформой. Это гарантирует, что графические объекты масштабируются соответствующим образом до плотности пикселей базовой платформы.

Рисование линии

Линии можно нарисовать с ICanvas помощью DrawLine метода, который требует четырех float аргументов, представляющих начальные и конечные точки линии.

В следующем примере показано, как нарисовать линию:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 6;
canvas.DrawLine(10, 10, 90, 100);

В этом примере красная диагонали рисуется от (10 10 10) до (90 100):

Screenshot of a red line.

Примечание.

Существует также перегрузка DrawLine , которая принимает два PointF аргумента.

В следующем примере показано, как нарисовать дефисированную линию:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawLine(10, 10, 90, 100);

В этом примере красная диагоналиная линия рисуется от (10,10) до (90 100):

Screenshot of a dashed red line.

Дополнительные сведения о дефишированных строках см. в разделе "Рисование дефисированных объектов".

Вывод эллипса

Многоточие и круги можно нарисовать с ICanvas помощью DrawEllipse метода, для которого требуются ywidthxаргументы и height аргументы типаfloat.

В следующем примере показано, как нарисовать многоточие:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 50);

В этом примере красное многоточие с измерениями 100x50 рисуется по адресу (10,10):

Screenshot of a red ellipse.

Чтобы нарисовать круг, сделайте width аргументы и height аргументы равным методу DrawEllipse :

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 100);

В этом примере красный круг с измерениями 100x100 рисуется по адресу (10 10 10):

Screenshot of a red circle.

Примечание.

Круги также можно нарисовать с DrawCircle помощью метода.

Сведения о рисовании тире многоточия см. в разделе "Рисование дефисированных объектов".

Заполненный эллипс можно нарисовать с FillEllipse помощью метода, который также требует x, ywidthи height аргументов типаfloat:

canvas.FillColor = Colors.Red;
canvas.FillEllipse(10, 10, 150, 50);

В этом примере рисуется красное многоточие с измерениями 150x50 (10 10):

Screenshot of a red filled ellipse.

ICanvas Свойство FillColor объекта должно быть задано перед Color вызовом FillEllipse метода.

Заполненные круги также можно нарисовать с FillCircle помощью метода.

Примечание.

Существуют и перегрузки, которые принимают DrawEllipseRect и FillEllipseRectF аргументы. Кроме того, существуют и DrawCircleFillCircle перегрузки.

Рисование прямоугольника

Прямоугольники и квадраты можно нарисовать с ICanvas помощью DrawRectangle метода, для которого требуются yxwidthаргументы и height аргументы типаfloat.

В следующем примере показано, как нарисовать прямоугольник:

canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 50);

В этом примере прямоугольник темно-синего цвета с измерениями 100x50 рисуется по адресу (10,10):

Screenshot of a dark blue rectangle.

Чтобы нарисовать квадрат, сделайте width аргументы и height аргументы равным методу DrawRectangle :

canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 100);

В этом примере темно-синий квадрат с измерениями 100x100 рисуется по адресу (10 10 10):

Screenshot of a dark blue square.

Сведения о рисовании тиреного прямоугольника см. в разделе "Рисование дефисированных объектов".

Заполненный прямоугольник можно нарисовать с FillRectangle помощью метода, который также требует x, ywidthи height аргументов типаfloat:

canvas.FillColor = Colors.DarkBlue;
canvas.FillRectangle(10, 10, 100, 50);

В этом примере прямоугольник с темно-синей заливкой с измерениями 100x50 рисуется по адресу (10 10 10):

Screenshot of a dark blue filled rectangle.

ICanvas Свойство FillColor объекта должно быть задано перед Color вызовом FillRectangle метода.

Примечание.

Существуют и перегрузки, которые принимают DrawRectangleRect и FillRectangleRectF аргументы.

Рисование округленного прямоугольника

Округленные прямоугольники и квадраты можно нарисовать с ICanvas помощью метода, для которого требуются xаргументы y, и heightwidthcornerRadius аргументы типа.floatDrawRoundedRectangle Аргумент cornerRadius задает радиус, используемый для округления углов прямоугольника.

В следующем примере показано, как нарисовать округленный прямоугольник:

canvas.StrokeColor = Colors.Green;
canvas.StrokeSize = 4;
canvas.DrawRoundedRectangle(10, 10, 100, 50, 12);

В этом примере зеленый прямоугольник с закругленными углами и измерениями 100x50 рисуется по адресу (10 10 10):

Screenshot of a green rounded rectangle.

Сведения о рисовании дефисированного прямоугольника с округленным округлением см. в разделе "Рисование дефисированных объектов".

Заполненный округленный прямоугольник можно нарисовать с FillRoundedRectangle помощью метода, который также требует x, y, widthи heightcornerRadius аргументов типаfloat:

canvas.FillColor = Colors.Green;
canvas.FillRoundedRectangle(10, 10, 100, 50, 12);

В этом примере зеленый прямоугольник с округленными углами и измерениями 100x50 рисуется по адресу (10 10 10):

Screenshot of a green filled rounded rectangle.

ICanvas Свойство FillColor объекта должно быть задано перед Color вызовом FillRoundedRectangle метода.

Примечание.

Существуют DrawRoundedRectangle и перегрузки, которые принимают Rect и FillRoundedRectangleRectF аргументы, и перегрузки, позволяющие задать радиус каждого угла отдельно.

Рисование дуги

Арки можно нарисовать с ICanvas помощью метода, который требует x, y, width, heightstartAngleи endAngle аргументы типа, а также clockwiseclosed аргументы типаfloatbool.DrawArc Аргумент startAngle задает угол от оси x к начальной точке дуги. Аргумент endAngle задает угол от оси x к конечной точке дуги. Аргумент clockwise указывает направление, в котором рисуется дуга, и closed аргумент указывает, будет ли конечная точка дуги подключена к начальной точке.

В следующем примере показано, как нарисовать дугу:

canvas.StrokeColor = Colors.Teal;
canvas.StrokeSize = 4;
canvas.DrawArc(10, 10, 100, 100, 0, 180, true, false);

В этом примере вырисовывается тековая дуга измерений 100x100 (10 10). Дуга рисуется по часовой стрелке от 0 до 180 градусов и не закрывается:

Screenshot of a teal arc.

Сведения о рисовании тиреной дуги см. в разделе "Рисование дефисированных объектов".

Заполненная дуга может быть нарисована с FillArc помощью метода, который требует x, y, width, heightstartAngleи аргументы типаfloat, а clockwiseendAngle также аргумент типаbool:

canvas.FillColor = Colors.Teal;
canvas.FillArc(10, 10, 100, 100, 0, 180, true);

В этом примере заполненная дуга 100x100 нарисована (10 10 10). Дуга рисуется по часовой стрелке от 0 до 180 градусов и закрывается автоматически:

Screenshot of a filled teal arc.

ICanvas Свойство FillColor объекта должно быть задано перед Color вызовом FillArc метода.

Примечание.

Существуют и перегрузки, которые принимают DrawArcRect и FillArcRectF аргументы.

Рисование контура

Путь — это коллекция одного или нескольких контуров. Каждый контур представляет собой коллекцию подключенных прямых линий и кривых. Контуры не связаны друг с другом, но они могут визуально перекрываться. Иногда один контур может перекрываться.

Пути используются для рисования кривых и сложных фигур и могут быть нарисованы с ICanvas помощью DrawPath метода, для которого требуется PathF аргумент.

Контур обычно начинается с вызова PathF.MoveTo метода, который можно выразить как значение, так и как PointF отдельные x и y координаты. Вызов MoveTo устанавливает точку в начале контура и начальную текущую точку. Затем можно вызвать следующие методы, чтобы продолжить контур с линией или кривой из текущей точки в точку, указанную в методе, которая затем становится новой текущей точкой:

  • LineTo Чтобы добавить прямую линию в путь.
  • AddArc для добавления дуги, которая является линией по окружности круга или многоточия.
  • CurveTo чтобы добавить кубическую spzier spline.
  • QuadTo чтобы добавить квадратичное spline Bezier.

Ни один из этих методов не содержит все данные, необходимые для описания линии или кривой. Вместо этого каждый метод работает с текущей точкой, установленной вызовом метода сразу перед ним. Например, LineTo метод добавляет прямую линию к контуру на основе текущей точки.

Контур заканчивается другим вызовом MoveTo, который начинает новый контур или вызов Close, который закрывает контур. Метод Close автоматически добавляет прямую линию от текущей точки к первой точке контура и помечает путь как закрытый.

Класс PathF также определяет другие методы и свойства. Следующие методы добавляют в путь целые контуры:

  • AppendEllipse добавляет к пути закрытый многоточие.
  • AppendCircle добавляет к пути контур закрытого круга.
  • AppendRectangle добавляет к пути контур закрытого прямоугольника.
  • AppendRoundedRectangle добавляет закрытый прямоугольник с округленными углами к пути.

В следующем примере показано, как нарисовать путь:

PathF path = new PathF();
path.MoveTo(40, 10);
path.LineTo(70, 80);
path.LineTo(10, 50);
path.Close();
canvas.StrokeColor = Colors.Green;
canvas.StrokeSize = 6;
canvas.DrawPath(path);

В этом примере рисуется закрытый зеленый треугольник:

Screenshot of a closed green triangle.

Заполненный путь можно нарисовать с FillPathпомощью аргумента PathF .

PathF path = new PathF();
path.MoveTo(40, 10);
path.LineTo(70, 80);
path.LineTo(10, 50);
canvas.FillColor = Colors.SlateBlue;
canvas.FillPath(path);

В этом примере рисуется заполненный синим треугольником:

Screenshot of a filled slate blue triangle.

ICanvas Свойство FillColor объекта должно быть задано перед Color вызовом FillPath метода.

Внимание

Метод FillPath имеет перегрузку, которая позволяет WindingMode задать заданный алгоритм заполнения, который задает используемый алгоритм заполнения. Дополнительные сведения см. в режимах ветвления.

Рисование изображения

Изображения могут быть нарисованы с помощью DrawImage метода, для которого требуется IImage аргумент, а yxтакже аргументы widthи height аргументы типаfloat.ICanvas

В следующем примере показано, как загрузить изображение и нарисовать его на холсте:

using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
#if IOS || ANDROID || MACCATALYST
using Microsoft.Maui.Graphics.Platform;
#elif WINDOWS
using Microsoft.Maui.Graphics.Win2D;
#endif

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
#if IOS || ANDROID || MACCATALYST
    // PlatformImage isn't currently supported on Windows.
    image = PlatformImage.FromStream(stream);
#elif WINDOWS
    image = new W2DImageLoadingService().FromStream(stream);
#endif
}

if (image != null)
{
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
using Microsoft.Maui.Graphics.Platform;

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

В этом примере образ извлекается из сборки и загружается в виде потока. Затем он рисуется по фактическому размеру (10 10 10):

Screenshot of an image.

Внимание

Для загрузки образа, внедренного в сборку, требуется, чтобы для образа было установлено значение Embedded Resource , а не MauiImage.

Рисование строки

Строки можно нарисовать с ICanvas помощью одной из DrawString перегрузок. Внешний вид каждой строки можно определить, задав FontFontColorсвойства и FontSize свойства. Выравнивание строк можно задать с помощью горизонтальных и вертикальных параметров выравнивания, которые выполняют выравнивание в ограничивающем поле строки.

Примечание.

Ограничивающий прямоугольник для строки определяется его xаргументами , widthyи height аргументами.

В следующих примерах показано, как нарисовать строки:

canvas.FontColor = Colors.Blue;
canvas.FontSize = 18;

canvas.Font = Font.Default;
canvas.DrawString("Text is left aligned.", 20, 20, 380, 100, HorizontalAlignment.Left, VerticalAlignment.Top);
canvas.DrawString("Text is centered.", 20, 60, 380, 100, HorizontalAlignment.Center, VerticalAlignment.Top);
canvas.DrawString("Text is right aligned.", 20, 100, 380, 100, HorizontalAlignment.Right, VerticalAlignment.Top);

canvas.Font = Font.DefaultBold;
canvas.DrawString("This text is displayed using the bold system font.", 20, 140, 350, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.Font = new Font("Arial");
canvas.FontColor = Colors.Black;
canvas.SetShadow(new SizeF(6, 6), 4, Colors.Gray);
canvas.DrawString("This text has a shadow.", 20, 200, 300, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

В этом примере отображаются строки с различными параметрами внешнего вида и выравнивания:

Screenshot of strings using different alignment options.

Примечание.

Перегрузки DrawString также позволяют усекать и интервалы между линиями.

Сведения о рисовании тени см. в разделе "Рисование тени".

Рисование атрибута текста

Текст атрибута можно нарисовать с ICanvas помощью DrawText метода, для которого требуется IAttributedText аргумент, и , widthyи xheight аргументы типаfloat. Атрибутный текст — это строка со связанными атрибутами для частей текста, которая обычно представляет данные стилей.

В следующем примере показано, как нарисовать текст с атрибутами:

using Microsoft.Maui.Graphics.Text;
...

canvas.Font = new Font("Arial");
canvas.FontSize = 18;
canvas.FontColor = Colors.Blue;

string markdownText = @"This is *italic text*, **bold text**, __underline text__, and ***bold italic text***.";
IAttributedText attributedText = MarkdownAttributedTextReader.Read(markdownText); // Requires the Microsoft.Maui.Graphics.Text.Markdig package
canvas.DrawText(attributedText, 10, 10, 400, 400);

В этом примере markdown преобразуется в текст с атрибутами и отображается с правильным стилем:

Screenshot of correctly rendered markdown.

Внимание

Для рисования текста с атрибутами Microsoft.Maui.Graphics.Text.Markdig необходимо добавить пакет NuGet в проект.

Рисование с заливкой и росчерком

Графические объекты с заливкой и росчерком можно нарисовать на холсте, вызвав метод рисования после метода заливки. Например, чтобы нарисовать контурный прямоугольник, задайте FillColor цвета и StrokeColor свойства, а затем вызовите FillRectangle метод, за которым следует DrawRectangle метод.

Следующий пример рисует заполненный круг с контуром росчерка в виде пути:

float radius = Math.Min(dirtyRect.Width, dirtyRect.Height) / 4;

PathF path = new PathF();
path.AppendCircle(dirtyRect.Center.X, dirtyRect.Center.Y, radius);

canvas.StrokeColor = Colors.Blue;
canvas.StrokeSize = 10;
canvas.FillColor = Colors.Red;

canvas.FillPath(path);
canvas.DrawPath(path);

В этом примере указываются цвета росчерка и заливки для PathF объекта. Заполненный круг рисуется, а затем черта контура круга:

Screenshot of a circle drawn with fill and stroke.

Предупреждение

Вызов метода рисования перед методом заливки приведет к неправильному z-упорядочению. Заливка будет вырисована по росчерку, и штрих не будет виден.

Рисование тени

Графические объекты, нарисованные на объекте ICanvas , могут применять тени с помощью SetShadow метода, который принимает следующие аргументы:

  • offset, тип SizeF, указывает смещение для тени, которая представляет позицию источника света, создающего тень.
  • blur, типа float, представляет объем размытия, применяемого к тени.
  • color, типа Color, определяет цвет тени.

В следующих примерах показано, как добавить тени в заполненные объекты:

canvas.FillColor = Colors.Red;
canvas.SetShadow(new SizeF(10, 10), 4, Colors.Grey);
canvas.FillRectangle(10, 10, 90, 100);

canvas.FillColor = Colors.Green;
canvas.SetShadow(new SizeF(10, -10), 4, Colors.Grey);
canvas.FillEllipse(110, 10, 90, 100);

canvas.FillColor = Colors.Blue;
canvas.SetShadow(new SizeF(-10, 10), 4, Colors.Grey);
canvas.FillRoundedRectangle(210, 10, 90, 100, 25);

В этих примерах тени, источники света которых находятся в разных позициях, добавляются в заполненные объекты с одинаковыми объемами размытия:

Screenshot of a objects drawn with shadows.

Рисование дефисированных объектов

ICanvas объекты имеют StrokeDashPattern свойство типа float[]. Это свойство представляет собой массив значений, указывающий шаблон дефисов float и пробелов, которые должны использоваться при рисовании росчерка для объекта. Каждая float из массивов задает длину тире или пробела. Первый элемент в массиве задает длину тире, а второй элемент в массиве задает длину пробела. float Поэтому значения с четным значением индекса указывают дефисы, а float значения с нечетным значением индекса указывают пробелы.

В следующем примере показано, как нарисовать тире квадрат, используя обычный тире:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawRectangle(10, 10, 90, 100);

В этом примере вырисовывается квадрат с регулярным пунктирной росчерком:

Screenshot of a regular dashed square.

В следующем примере показано, как нарисовать тире квадрат, используя нерегулярный тире:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 4, 4, 1, 4 };
canvas.DrawRectangle(10, 10, 90, 100);

В этом примере рисуется квадрат с нерегулярным тиреным штрихом:

Screenshot of an irregular dashed square.

Концы строки управления

Строка состоит из трех частей: начальная крышка, тело строки и конец. Начальные и конечные крышки описывают начало и конец строки.

ICanvas Объекты имеют StrokeLineCap свойство типа LineCap, описывающее начало и конец строки. Перечисление LineCap определяет следующие члены:

  • Butt, представляющий линию с квадратным концом, рисуемую для расширения до точной конечной точки линии. Это значение по умолчанию для свойства StrokeLineCap.
  • Round, представляющий линию с округленным концом.
  • Square, представляющий линию с квадратным концом, рисуемую для расширения за пределами конечной точки до расстояния, равного половине ширины линии.

В следующем примере показано, как задать свойство StrokeLineCap:

canvas.StrokeSize = 10;
canvas.StrokeColor = Colors.Red;
canvas.StrokeLineCap = LineCap.Round;
canvas.DrawLine(10, 10, 110, 110);

В этом примере красная линия округляется в начале и конце строки:

Screenshot of three lines with different line caps.

Соединения линий управления

ICanvas объекты имеют StrokeLineJoin свойство типа LineJoin, указывающее тип соединения, который используется в вершинах объекта. Перечисление LineJoin определяет следующие члены:

  • Miter, представляющий угловые вершины, которые создают острый или обрезанный угол. Это значение по умолчанию для свойства StrokeLineJoin.
  • Round, представляющий округленные вершины, которые создают круговую дугу в углу.
  • Bevel, представляющий вырезные вершины, которые создают диагональный угол.

Примечание.

StrokeLineJoin Если для свойства задано Miterзначение, MiterLimit свойство можно задать для float ограничения длины мизера соединения строк в объекте.

В следующем примере показано, как задать свойство StrokeLineJoin:

PathF path = new PathF();
path.MoveTo(10, 10);
path.LineTo(110, 50);
path.LineTo(10, 110);

canvas.StrokeSize = 20;
canvas.StrokeColor = Colors.Blue;
canvas.StrokeLineJoin = LineJoin.Round;
canvas.DrawPath(path);

В этом примере синий PathF объект округляет соединения по вершинам:

Screenshot of the effect of the three different LineJoin enumeration members.

Объекты клипа

Графические объекты, нарисованные к объекту ICanvas , можно обрезать перед рисованием с помощью следующих методов:

  • ClipPath клипирует объект таким образом, чтобы отображалось только область, которая находится в пределах области PathF объекта.
  • ClipRectangle клипирует объект таким образом, чтобы отображалось только область, которая находится в пределах области прямоугольника. Прямоугольник можно указать с помощью float аргументов или RectRectF аргументов.
  • SubtractFromClip клипирует объект таким образом, чтобы отображалось только область, которая находится за пределами области прямоугольника. Прямоугольник можно указать с помощью float аргументов или RectRectF аргументов.

В следующем примере показано, как использовать ClipPath метод для клипа изображения:

using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
#if IOS || ANDROID || MACCATALYST
using Microsoft.Maui.Graphics.Platform;
#elif WINDOWS
using Microsoft.Maui.Graphics.Win2D;
#endif

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
#if IOS || ANDROID || MACCATALYST
    // PlatformImage isn't currently supported on Windows.
    image = PlatformImage.FromStream(stream);
#elif WINDOWS
    image = new W2DImageLoadingService().FromStream(stream);
#endif
}

if (image != null)
{
    PathF path = new PathF();
    path.AppendCircle(100, 90, 80);
    canvas.ClipPath(path);  // Must be called before DrawImage
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
using Microsoft.Maui.Graphics.Platform;

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    PathF path = new PathF();
    path.AppendCircle(100, 90, 80);
    canvas.ClipPath(path);  // Must be called before DrawImage
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

В этом примере изображение обрезается с помощью PathF объекта, определяющего круг, в центре в центре (100 90) с радиусом 80. Результатом является то, что отображается только часть изображения в кругу:

Screenshot of an image that's been clipped with the ClipPath method.

Внимание

Метод ClipPath имеет перегрузку, которая позволяет WindingMode задать алгоритм заполнения, используемый при вырезки. Дополнительные сведения см. в режимах ветвления.

В следующем примере показано, как использовать SubtractFromClip метод для клипа изображения:

using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
#if IOS || ANDROID || MACCATALYST
using Microsoft.Maui.Graphics.Platform;
#elif WINDOWS
using Microsoft.Maui.Graphics.Win2D;
#endif

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
#if IOS || ANDROID || MACCATALYST
    // PlatformImage isn't currently supported on Windows.
    image = PlatformImage.FromStream(stream);
#elif WINDOWS
    image = new W2DImageLoadingService().FromStream(stream);
#endif
}

if (image != null)
{
    canvas.SubtractFromClip(60, 60, 90, 90);
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
using System.Reflection;
using IImage = Microsoft.Maui.Graphics.IImage;
using Microsoft.Maui.Graphics.Platform;

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    canvas.SubtractFromClip(60, 60, 90, 90);
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

В этом примере область, определяемая прямоугольником, заданным аргументами метода SubtractFromClip , обрезается из изображения. Результатом является то, что видимы только части изображения за пределами прямоугольника:

Screenshot of an image that's been clipped with the SubtractFromClip method.