Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
.NET Multi-platform App UI (.NET MAUI) graphics, in the Microsoft.Maui.Graphics namespace, enables you to draw graphical objects on a canvas that's defined as an ICanvas object.
The .NET MAUI GraphicsView control provides access to an ICanvas object, on which properties can be set and methods invoked to draw graphical objects. For more information about the GraphicsView, see GraphicsView.
Note
Many of the graphical objects have Draw
and Fill
methods, for example DrawRectangle and FillRectangle. A Draw
method draws the outline of the shape, which is unfilled. A Fill
method draws the outline of the shape and also fills it.
Graphical objects are drawn on an ICanvas using a device-independent unit that's recognized by each platform. This ensures that graphical objects are scaled appropriately to the pixel density of the underlying platform.
Lines can be drawn on an ICanvas using the DrawLine method, which requires four float
arguments that represent the start and end points of the line.
The following example shows how to draw a line:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 6;
canvas.DrawLine(10, 10, 90, 100);
In this example, a red diagonal line is drawn from (10,10) to (90,100):
The following example shows how to draw a dashed line:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawLine(10, 10, 90, 100);
In this example, a red dashed diagonal line is drawn from (10,10) to (90,100):
For more information about dashed lines, see Draw dashed objects.
Ellipses and circles can be drawn on an ICanvas using the DrawEllipse method, which requires x
, y
, width
, and height
arguments, of type float
.
The following example shows how to draw an ellipse:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 50);
In this example, a red ellipse with dimensions 100x50 is drawn at (10,10):
To draw a circle, make the width
and height
arguments to the DrawEllipse method equal:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 100);
In this example, a red circle with dimensions 100x100 is drawn at (10,10):
Note
Circles can also be drawn with the DrawCircle method.
For information about drawing a dashed ellipse, see Draw dashed objects.
A filled ellipse can be drawn with the FillEllipse method, which also requires x
, y
, width
, and height
arguments, of type float
:
canvas.FillColor = Colors.Red;
canvas.FillEllipse(10, 10, 150, 50);
In this example, a red filled ellipse with dimensions 150x50 is drawn at (10,10):
The FillColor property of the ICanvas object must be set to a Color before invoking the FillEllipse method.
Filled circles can also be drawn with the FillCircle method.
Note
There are DrawEllipse and FillEllipse overloads that take Rect and RectF arguments. In addition, there are also DrawCircle and FillCircle overloads.
Rectangles and squares can be drawn on an ICanvas using the DrawRectangle method, which requires x
, y
, width
, and height
arguments, of type float
.
The following example shows how to draw a rectangle:
canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 50);
In this example, a dark blue rectangle with dimensions 100x50 is drawn at (10,10):
To draw a square, make the width
and height
arguments to the DrawRectangle method equal:
canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 100);
In this example, a dark blue square with dimensions 100x100 is drawn at (10,10):
For information about drawing a dashed rectangle, see Draw dashed objects.
A filled rectangle can be drawn with the FillRectangle method, which also requires x
, y
, width
, and height
arguments, of type float
:
canvas.FillColor = Colors.DarkBlue;
canvas.FillRectangle(10, 10, 100, 50);
In this example, a dark blue filled rectangle with dimensions 100x50 is drawn at (10,10):
The FillColor property of the ICanvas object must be set to a Color before invoking the FillRectangle method.
Note
There are DrawRectangle and FillRectangle overloads that take Rect and RectF arguments.
Rounded rectangles and squares can be drawn on an ICanvas using the DrawRoundedRectangle method, which requires x
, y
, width
, height
, and cornerRadius
arguments, of type float
. The cornerRadius
argument specifies the radius used to round the corners of the rectangle.
The following example shows how to draw a rounded rectangle:
canvas.StrokeColor = Colors.Green;
canvas.StrokeSize = 4;
canvas.DrawRoundedRectangle(10, 10, 100, 50, 12);
In this example, a green rectangle with rounded corners and dimensions 100x50 is drawn at (10,10):
For information about drawing a dashed rounded rectangle, see Draw dashed objects.
A filled rounded rectangle can be drawn with the FillRoundedRectangle method, which also requires x
, y
, width
, height
, and cornerRadius
arguments, of type float
:
canvas.FillColor = Colors.Green;
canvas.FillRoundedRectangle(10, 10, 100, 50, 12);
In this example, a green filled rectangle with rounded corners and dimensions 100x50 is drawn at (10,10):
The FillColor property of the ICanvas object must be set to a Color before invoking the FillRoundedRectangle method.
Note
There are DrawRoundedRectangle and FillRoundedRectangle overloads that take Rect and RectF arguments, and overloads that enable the radius of each corner to be separately specified.
Arcs can be drawn on an ICanvas using the DrawArc method, which requires x
, y
, width
, height
, startAngle
, and endAngle
arguments of type float
, and clockwise
and closed
arguments of type bool
. The startAngle
argument specifies the angle from the x-axis to the starting point of the arc. The endAngle
argument specifies the angle from the x-axis to the end point of the arc. The clockwise
argument specifies the direction in which the arc is drawn, and the closed
argument specifies whether the end point of the arc will be connected to the start point.
The following example shows how to draw an arc:
canvas.StrokeColor = Colors.Teal;
canvas.StrokeSize = 4;
canvas.DrawArc(10, 10, 100, 100, 0, 180, true, false);
In this example, a teal arc of dimensions 100x100 is drawn at (10,10). The arc is drawn in a clockwise direction from 0 degrees to 180 degrees, and isn't closed:
For information about drawing a dashed arc, see Draw dashed objects.
A filled arc can be drawn with the FillArc method, which requires x
, y
, width
, height
, startAngle
, and endAngle
arguments of type float
, and a clockwise
argument of type bool
:
canvas.FillColor = Colors.Teal;
canvas.FillArc(10, 10, 100, 100, 0, 180, true);
In this example, a filled teal arc of dimensions 100x100 is drawn at (10,10). The arc is drawn in a clockwise direction from 0 degrees to 180 degrees, and is closed automatically:
The FillColor property of the ICanvas object must be set to a Color before invoking the FillArc method.
A path is a collection of one or more contours. Each contour is a collection of connected straight lines and curves. Contours are not connected to each other but they might visually overlap. Sometimes a single contour can overlap itself.
Paths are used to draw curves and complex shapes and can be drawn on an ICanvas using the DrawPath method, which requires a PathF argument.
A contour generally begins with a call to the PathF.MoveTo method, which you can express either as a PointF value or as separate x
and y
coordinates. The MoveTo call establishes a point at the beginning of the contour and an initial current point. You can then call the following methods to continue the contour with a line or curve from the current point to a point specified in the method, which then becomes the new current point:
None of these methods contain all of the data necessary to describe the line or curve. Instead, each method works with the current point established by the method call immediately preceding it. For example, the LineTo method adds a straight line to the contour based on the current point.
A contour ends with another call to MoveTo, which begins a new contour, or a call to Close, which closes the contour. The Close method automatically appends a straight line from the current point to the first point of the contour, and marks the path as closed.
The PathF class also defines other methods and properties. The following methods add entire contours to the path:
The following example shows how to draw a path:
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);
In this example, a closed green triangle is drawn:
A filled path can be drawn with the FillPath, which also requires a PathF argument:
PathF path = new PathF();
path.MoveTo(40, 10);
path.LineTo(70, 80);
path.LineTo(10, 50);
canvas.FillColor = Colors.SlateBlue;
canvas.FillPath(path);
In this example, a filled slate blue triangle is drawn:
The FillColor property of the ICanvas object must be set to a Color before invoking the FillPath method.
Important
The FillPath method has an overload that enables a WindingMode to be specified, which sets the fill algorithm that's used. For more information, see Winding modes.
Images can be drawn on an ICanvas using the DrawImage method, which requires an IImage argument, and x
, y
, width
, and height
arguments, of type float
.
The following example shows how to load an image and draw it to the canvas:
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);
}
In this example, an image is retrieved from the assembly and loaded as a stream. It's then drawn at actual size at (10,10):
Important
Loading an image that's embedded in an assembly requires the image to have its build action set to Embedded Resource rather than MauiImage.
Strings can be drawn on an ICanvas using one of the DrawString overloads. The appearance of each string can be defined by setting the Font, FontColor, and FontSize properties. String alignment can be specified by horizontal and vertical alignment options that perform alignment within the string's bounding box.
Note
The bounding box for a string is defined by its x
, y
, width
, and height
arguments.
The following examples show how to draw strings:
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);
In this example, strings with different appearance and alignment options are displayed:
Note
The DrawString overloads also enable truncation and line spacing to be specified.
For information about drawing shadows, see Draw a shadow.
Attributed text can be drawn on an ICanvas using the DrawText method, which requires an IAttributedText argument, and x
, y
, width
, and height
arguments, of type float
. Attributed text is a string with associated attributes for parts of its text, that typically represents styling data.
The following example shows how to draw attributed text:
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);
In this example, markdown is converted to attributed text and displayed with the correct styling:
Important
Drawing attributed text requires you to have added the Microsoft.Maui.Graphics.Text.Markdig
NuGet package to your project.
Graphical objects with both fill and stroke can be drawn to the canvas by calling a draw method after a fill method. For example, to draw an outlined rectangle, set the FillColor and StrokeColor properties to colors, then call the FillRectangle method followed by the DrawRectangle method.
The following example draws a filled circle, with a stroke outline, as a path:
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);
In this example, the stroke and fill colors for a PathF object are specified. The filled circle is drawn, then the outline stroke of the circle:
Warning
Calling a draw method before a fill method will result in an incorrect z-order. The fill will be drawn over the stroke, and the stroke won't be visible.
Graphical objects drawn on an ICanvas can have a shadow applied using the SetShadow method, which takes the following arguments:
offset
, of type SizeF, specifies an offset for the shadow, which represents the position of a light source that creates the shadow.blur
, of type float
, represents the amount of blur to apply to the shadow.color
, of type Color, defines the color of the shadow.The following examples show how to add shadows to filled objects:
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);
In these examples, shadows whose light sources are in different positions are added to the filled objects, with identical amounts of blur:
ICanvas objects have a StrokeDashPattern property, of type float[]
. This property is an array of float
values that indicate the pattern of dashes and gaps that are to be used when drawing the stroke for an object. Each float
in the array specifies the length of a dash or gap. The first item in the array specifies the length of a dash, while the second item in the array specifies the length of a gap. Therefore, float
values with an even index value specify dashes, while float
values with an odd index value specify gaps.
The following example shows how to draw a dashed square, using a regular dash:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawRectangle(10, 10, 90, 100);
In this example, a square with a regular dashed stroke is drawn:
The following example shows how to draw a dashed square, using an irregular dash:
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 4, 4, 1, 4 };
canvas.DrawRectangle(10, 10, 90, 100);
In this example, a square with an irregular dashed stroke is drawn:
A line has three parts: start cap, line body, and end cap. The start and end caps describe the start and end of a line.
ICanvas objects have a StrokeLineCap property, of type LineCap, that describes the start and end of a line. The LineCap enumeration defines the following members:
Butt
, which represents a line with a square end, drawn to extend to the exact endpoint of the line. This is the default value of the StrokeLineCap property.Round
, which represents a line with a rounded end.Square
, which represents a line with a square end, drawn to extend beyond the endpoint to a distance equal to half the line width.The following example shows how to set the StrokeLineCap property:
canvas.StrokeSize = 10;
canvas.StrokeColor = Colors.Red;
canvas.StrokeLineCap = LineCap.Round;
canvas.DrawLine(10, 10, 110, 110);
In this example, the red line is rounded at the start and end of the line:
ICanvas objects have a StrokeLineJoin property, of type LineJoin, that specifies the type of join that is used at the vertices of an object. The LineJoin enumeration defines the following members:
Miter
, which represents angular vertices that produce a sharp or clipped corner. This is the default value of the StrokeLineJoin property.Round
, which represents rounded vertices that produce a circular arc at the corner.Bevel
, which represents beveled vertices that produce a diagonal corner.Note
When the StrokeLineJoin property is set to Miter
, the MiterLimit
property can be set to a float
to limit the miter length of line joins in the object.
The following example shows how to set the StrokeLineJoin property:
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);
In this example, the blue PathF object has rounded joins at its vertices:
Graphical objects that are drawn to an ICanvas can be clipped prior to drawing, with the following methods:
float
arguments, or by a Rect or RectF argument.float
arguments, or by a Rect or RectF argument.The following example shows how to use the ClipPath method to clip an image:
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);
}
In this example, the image is clipped using a PathF object that defines a circle that's centered at (100,90) with a radius of 80. The result is that only the part of the image within the circle is visible:
Important
The ClipPath method has an overload that enables a WindingMode to be specified, which sets the fill algorithm that's used when clipping. For more information, see Winding modes.
The following example shows how to use the SubtractFromClip method to clip an image:
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);
}
In this example, the area defined by the rectangle that's specified by the arguments supplied to the SubtractFromClip method is clipped from the image. The result is that only the parts of the image outside the rectangle are visible:
.NET MAUI feedback
.NET MAUI is an open source project. Select a link to provide feedback:
Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register now