SkCanvas
The SkCanvas class in SkiaSharp is the primary drawing surface. It provides a rich API for drawing 2D graphics, including shapes, text, images, and more. All drawing operations are performed on an instance of SkCanvas.
Overview
An SkCanvas object acts as a drawing context. You obtain an SkCanvas instance from a surface, such as an SKBitmap, SKPixmap, or a platform-specific surface (like those used in UI frameworks). Once you have a canvas, you can issue drawing commands. These commands are often immutable, meaning once created, they cannot be changed. This design pattern is common in graphics libraries for performance and thread-safety.
Key concepts associated with SkCanvas include:
- Drawing Primitives: Methods for drawing basic shapes like points, lines, rectangles, ovals, and arcs.
- Paths: Advanced shape definition using the
SKPathclass. - Text: Drawing text with various fonts, styles, and colors.
- Images: Rendering
SKBitmaporSKPixmapobjects. - Transformations: Applying transformations like translation, scaling, rotation, and skewing to the coordinate system.
- Clipping: Restricting drawing operations to specific regions of the canvas.
- State Management: Saving and restoring the drawing state (transformations, clipping, paint properties) using
Save()andRestore().
Getting an SkCanvas
You typically get an SkCanvas from an SKSurface. An SKSurface encapsulates the drawing buffer and provides access to its canvas.
// Example using SKBitmap
var bitmap = new SKBitmap(100, 100);
using (var surface = SKSurface.Create(bitmap.Info))
{
var canvas = surface.Canvas;
// Draw on the canvas here
}
// Example using SKImageInfo
var info = new SKImageInfo(200, 200, SKImageInfo.PlatformColorType, SKAlphaType.Premul);
using (var surface = SKSurface.Create(info))
{
var canvas = surface.Canvas;
// Draw on the canvas here
}
Common Drawing Methods
The SkCanvas class offers a wide array of methods for drawing. Here are some of the most frequently used:
Drawing Shapes
void DrawRect(SKRect rect, SKPaint paint)
Draws a rectangle.
void DrawCircle(float cx, float cy, float radius, SKPaint paint)
Draws a circle.
void DrawOval(SKRect oval, SKPaint paint)
Draws an oval.
void DrawLine(float x0, float y0, float x1, float y1, SKPaint paint)
Draws a line segment.
Drawing Paths
void DrawPath(SKPath path, SKPaint paint)
Draws a custom path.
Drawing Text
void DrawText(string text, float x, float y, SKPaint paint)
Draws text at a specified position. Note that 'y' is the baseline of the text.
Drawing Images
void DrawBitmap(SKBitmap bitmap, float x, float y, SKPaint paint = null)
Draws a bitmap at a specified position.
void DrawImage(SKImage image, float x, float y, SKPaint paint = null)
Draws an image at a specified position.
Transformations
void Translate(float dx, float dy)
Translates the canvas's coordinate system.
void Scale(float sx, float sy)
Scales the canvas's coordinate system.
void RotateDegrees(float degrees)
Rotates the canvas's coordinate system.
void Save()
Pushes the current canvas state onto the state stack.
void Restore()
Pops the last canvas state from the state stack.
void ClipRect(SKRect rect)
Intersects the current clip with the specified rectangle.
Example: Drawing a Filled and Stroked Rectangle
using SkiaSharp;
// Assume 'canvas' is an initialized SKCanvas instance
// Define a rectangle
var rect = new SKRect(50, 50, 150, 100); // x0, y0, x1, y1
// Create a paint for filling
var fillPaint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.CornflowerBlue,
IsAntialias = true
};
// Create a paint for stroking
var strokePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Black,
StrokeWidth = 2,
IsAntialias = true
};
// Draw the filled rectangle
canvas.DrawRect(rect, fillPaint);
// Draw the stroke around the rectangle
canvas.DrawRect(rect, strokePaint);
State Management with Save/Restore
The Save() and Restore() methods are crucial for managing transformations and clipping regions. When you call Save(), the current state of the canvas (including transformations, clip regions, and paint properties that are part of the state) is pushed onto a stack. Calling Restore() pops the last saved state off the stack, reverting the canvas to that state. This is very useful for applying temporary transformations without affecting subsequent drawing operations.
// Draw a red circle at the origin
var redPaint = new SKPaint { Color = SKColors.Red };
canvas.DrawCircle(0, 0, 20, redPaint);
// Save the current state
canvas.Save();
// Apply a translation and rotation
canvas.Translate(100, 100);
canvas.RotateDegrees(45);
// Draw a blue rectangle in the transformed coordinate system
var bluePaint = new SKPaint { Color = SKColors.Blue };
var rect = new SKRect(-50, -25, 50, 25); // Centered around the new origin
canvas.DrawRect(rect, bluePaint);
// Restore to the state before translation and rotation
canvas.Restore();
// Now, drawing will be back to the original coordinate system.
// This red circle will be drawn again, but unaffected by the previous transforms.
canvas.DrawCircle(0, 0, 20, redPaint);
Antialiasing
For smoother edges on shapes and text, ensure that IsAntialias is set to true on your SKPaint objects when appropriate.