Sharp.Canvas 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Sharp.Canvas --version 1.0.0
                    
NuGet\Install-Package Sharp.Canvas -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sharp.Canvas" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sharp.Canvas" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Sharp.Canvas" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Sharp.Canvas --version 1.0.0
                    
#r "nuget: Sharp.Canvas, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=Sharp.Canvas&version=1.0.0
                    
Install Sharp.Canvas as a Cake Addin
#tool nuget:?package=Sharp.Canvas&version=1.0.0
                    
Install Sharp.Canvas as a Cake Tool

SharpCanvas

SharpCanvas is a lightweight and easy-to-use WPF control for drawing and rendering 2D graphics. It provides a simple and intuitive API for drawing shapes, text, and images, and supports a wide range of drawing options such as fill, stroke, and shadow.

Also supports interactivity, including mouse and touch input for editing shapes; Zooming, panning, and selection is also supported for interactive editing.

Finally, you can export the drawn graphics as a bitmap in any size, and the shapes in canvas would be preserved and keep ratio.

Shapes

  • Circle
  • Ellipse with angle
  • Line define by start and end point
  • Polygon define by points
  • Cross define by single point
  • Rectangle1D
  • Rectangle2D with angle
  • Text
  • Image

Shape Structures

Circle
public record Circle : IShapeStructure
{
    public double Radius;
    public double CenterX;
    public double CenterY;
}
Ellipse
public record Ellipse : IShapeStructure
{
    public double RadiusX;
    public double RadiusY;
    public double CenterX;
    public double CenterY;
    public double RotationDegree;
}
Line
public record Line : IShapeStructure
{
    public double X1;
    public double Y1;
    public double X2;
    public double Y2;
}
Polygon
public record Polygon : IShapeStructure
{
    public List<Point> Points;
    public bool IsClosed;
}
Cross
public record Cross : IShapeStructure
{
    public double Size;
    public Point Center;
    public double AngleDegree;
}
Rectangle1D
public record Rectangle1D : IShapeStructure
{
    public double Width;
    public double Height;
    public double X;
    public double Y;
}
Rectangle2D with angle
public record Rectangle2D : IShapeStructure
{
    public double HalfWidth;
    public double HalfHeight;
    public double CenterX;
    public double CenterY;
    public double AngleDegree;
}
Text
public record Text : IShapeStructure
{
    public string _Text;
    public double X;
    public double Y;
    public SolidColorBrush Brush = null;
    public double FontSize = 16;
}
Image

BitmapFrame is used to represent the image.

Interfaces Oveview

public interface ICVCanvas
{
    //--------------------------------Display----------------------------
    void CV_DisplayImage(
        BitmapFrame image,
        double x = 0,
        double y = 0,
        double width = 0,
        double height = 0,
        double canvasW = 0,
        double canvasH = 0
    );
    void CV_DisplayRectangle1D(Rectangle1D rectangle1D, double canvasW = 0, double canvasH = 0);
    void CV_DisplayRectangle1Ds(
        List<Rectangle1D> rectangle1D,
        double canvasW = 0,
        double canvasH = 0
    );
    void CV_DisplayRectangle2D(Rectangle2D rectangle2D, double canvasW = 0, double canvasH = 0);
    void CV_DisplayRectangle2Ds(
        List<Rectangle2D> rectangle2D,
        double canvasW = 0,
        double canvasH = 0
    );
    void CV_DisplayCircle(Circle circle, double canvasW = 0, double canvasH = 0);
    void CV_DisplayCircles(List<Circle> circles, double canvasW = 0, double canvasH = 0);
    void CV_DisplayEllipse(Structure.Ellipse ellipse, double canvasW = 0, double canvasH = 0);
    void CV_DisplayEllipses(
        List<Structure.Ellipse> ellipses,
        double canvasW = 0,
        double canvasH = 0
    );
    void CV_DisplayCross(Cross cross, double canvasW = 0, double canvasH = 0);
    void CV_DisplayCrosses(List<Cross> crosses, double canvasW = 0, double canvasH = 0);
    void CV_DisplayLine(Structure.Line line, double canvasW = 0, double canvasH = 0);
    void CV_DisplayLines(List<Structure.Line> lines, double canvasW = 0, double canvasH = 0);
    void CV_DisplayText(Text text, double canvasW = 0, double canvasH = 0);
    void CV_DisplayPolygon(
        Structure.Polygon polygon,
        bool isClosed = true,
        double canvasW = 0,
        double canvasH = 0
    );
    void CV_DisplayPolygons(
        List<Structure.Polygon> polygons,
        bool isClosed = true,
        double canvasW = 0,
        double canvasH = 0
    );

    //------------------------------Attachments------------------------------
    void CV_AttachRectangle1DToCanvas(string name, Rectangle1D rectangle1D);
    void CV_AttachRectangle2DToCanvas(string name, Rectangle2D rectangle2D);
    void CV_AttachCrossToCanvas(string name, Cross cross);
    void CV_AttachCircleToCanvas(string name, Circle circle);
    void CV_AttachEllipseToCanvas(string name, Structure.Ellipse ellipse);
    void CV_AttachLineToCanvas(string name, Structure.Line line);
    void CV_AttachPolygonToCanvas(string name, Structure.Polygon polygon);

    //----------Operations----------
    void CV_FitImageToCanvas(double canvasW = 0, double canvasH = 0);
    T CV_GetAttachStruture<T>(string name)
        where T : IShapeStructure;
    void CV_Detach(string name);
    void CV_SetStrokeColor(Brush brush, double thickness, int opacity = 100);
    void CV_SetFillColor(Brush brush, int opacity = 100);
    Task<BitmapFrame> CV_Dump(int width = 0, int height = 0);
    void CV_ClearShapes();
    void CV_Clear();
    void CV_SetThumbSize(int size);
}

Usage

Create a Canvas

<sharpCanvas:MyCanvas x:Name="myCanvas"  ClipToBounds="True"
xmlns:sharpCanvas="clr-namespace:SharpCanvas;assembly=SharpCanvas"/>

Configurations

//adjust the fill of the shapes displayed
myCanvas.CV_SetFillColor(Brushes.Yellow, 30);
//adjust the stroke of the shapes displayed
myCanvas.CV_SetStrokeColor(Brushes.Red, 1);
//adjust the size of the thumb for editing shapes
myCanvas.CV_SetThumbSize(10);

Display Shapes

Circle
myCanvas.CV_DisplayCircle(new(100, 200, 200));
Ellipse
myCanvas.CV_DisplayEllipse(new(100, 50, 200, 200));
Line
myCanvas.CV_DisplayLine(new(100, 100, 200, 200));
Polygon
// draw heart shape
var points = new List<Point>();
int numPoints = 50;
double scale = 10; // adjust the size of the heart

for (int i = 0; i < numPoints; i++)
{
    double t = 2 * Math.PI * i / numPoints;
    double x = scale * (16 * Math.Pow(Math.Sin(t), 3));
    double y =
        -scale
        * (13 * Math.Cos(t) - 5 * Math.Cos(2 * t) - 2 * Math.Cos(3 * t) - Math.Cos(4 * t));
    points.Add(new Point(x, y));
}
myCanvas.CV_SetFillColor(Brushes.Pink, 70);
myCanvas.CV_DisplayPolygon(
    new SharpCanvas.Shapes.Structure.Polygon(points.Translate(300, 300), false)
);
Cross
var height = this.myCanvas.m_currentImage.PixelHeight;
var width = this.myCanvas.m_currentImage.PixelWidth;
var random = new Random();
var crosses = new List<Point>();
this.myCanvas.CV_SetStrokeColor(Brushes.Red, 1);
for (int i = 0; i < 5000; i++)
{
    var x = random.Next(0, (int)width);
    var y = random.Next(0, (int)height);
    crosses.Add(new Point(x, y));
}
List<Cross> crosses1 = crosses.Select(p => new Cross(p, 45, 5)).ToList();
var sw = Stopwatch.StartNew();
this.myCanvas.CV_DisplayCrosses(crosses1);
sw.Stop();
Rectangle1D
var rect = new Rectangle1D(100, 100, 200, 200);
myCanvas.CV_DisplayRectangle1D(rect);
Rectangle2D
var rd = new Random();
var rects = new List<Rectangle2D>();
for (int i = 0; i < 10000; i++)
{
    var rect = new Rectangle2D(
        100,
        100,
        rd.Next(100, myCanvas.m_currentImage.PixelWidth - 100),
        rd.Next(100, myCanvas.m_currentImage.PixelHeight - 100),
        45
    );
    rects.Add(rect);
}

var sw = Stopwatch.StartNew();

for (int i = 0; i < 10000; i++)
{
    myCanvas.CV_DisplayRectangle2D(rects[i]);
}

sw.Stop();
Text
myCanvas.CV_DisplayText(
    new Text(
        "Visiter the on more on the mefilled dream this agreeing the vainly velvet raven front smiling the soul prophet the",
        12,
        12,
        Brushes.Blue,
        16
    )
);
Image
var path = @"D:\Image.bmp";
BitmapFrame image = BitmapFrame.Create(new Uri(path));
myCanvas.CV_DisplayImage(image);

Attach Shapes(Interactivity)

//attach a rectangle to the canvas
myCanvas.CV_AttachRectangle1DToCanvas("rect1", new Rectangle1D(100, 100, 200, 200));
//attach a circle to the canvas
myCanvas.CV_AttachCircleToCanvas("circle1", new Circle(100, 100, 50));

Attach a start with polygon to the canvas Star Attach a 45�� ellipse to the canvas 45�� Ellipse

Detach Shapes

myCanvas.CV_Detach("rect1");
myCanvas.CV_Detach("circle1");

Get Attach Structure

var rect = myCanvas.CV_GetAttachStruture<Rectangle1D>("rect1");
var circle = myCanvas.CV_GetAttachStruture<Circle>("circle1");

Clear Shapes

Note: This will not clear the image displayed on the canvas.

myCanvas.CV_ClearShapes();

Clear Canvas

Note: This will clear all the shapes and the image displayed on the canvas.

myCanvas.CV_Clear();

Dump to Bitmap

var path = SaveFileDialog(false, "jpg");
if (string.IsNullOrEmpty(path))
{
    return;
}
var bmp = myCanvas.CV_Dump(3000, 3000).GetAwaiter().GetResult();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(bmp);
using var fs = new FileStream(path, FileMode.Create);
encoder.Save(fs);

Quick Start

  1. Create a new WPF project in Visual Studio.
  2. Add a reference to the SharpCanvas library.
  3. Add a Canvas control to your XAML file.
  4. Add the following code to your XAML file:
<sharpCanvas:MyCanvas x:Name="myCanvas"  ClipToBounds="True"
xmlns:sharpCanvas="clr-namespace:SharpCanvas;assembly=SharpCanvas"/>
  1. Add the following code to your code-behind file:
//draw a circle
myCanvas.CV_DisplayCircle(new(100, 200, 200));
  1. Run the application.
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net472 is compatible.  net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.5 221 3/5/2025
1.0.4 138 9/2/2024
1.0.3 143 8/23/2024
1.0.2 157 8/10/2024
1.0.1 93 7/25/2024
1.0.0 151 7/19/2024

First Update