Does SkiaSharp possess the capabilities to allow an application to freehand draw directly onto an image? I can't figure out how to make the canvas not just a blank white screen, but have the canvas paint surface be the actual image itself. Has anyone been able to accomplish this?
I am able to transform my image to a canvas and separately am able to annotate directly onto a white screen (as in the SkiaSharp demo), but cannot figure out how to make the SKCanvas canvas var (that I created from my image) the surface that the SKPaths are being drawn on.
I should think so. Take a look at these guides:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/bitmaps
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/circle
Not sure what you want to draw over the image, but just do all of your drawing in the handler for the SKCanvasView.PaintSurface event handler, i.e. draw your bitmap image and then draw whatever else you want, circle, points, lines, more images, whatever. The following will draw an image and then any points that you have in List<SKPoint> points
:
skiaSharpView = new SKCanvasView { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand, }; skiaSharpView.PaintSurface += SkiaSharpView_PaintSurface; void SkiaSharpView_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); // Get the image from an EmbeddedResource string resourceID = "TestSkiaSharp.image.png"; Assembly assembly = GetType().GetTypeInfo().Assembly; using (Stream stream = assembly.GetManifestResourceStream(resourceID)) { resourceBitmap = SKBitmap.Decode(stream); } if (resourceBitmap != null) { // draw image to center of canvas canvas.DrawBitmap(resourceBitmap,info.Width / 2 - resourceBitmap.Width / 2, info.Height / 2 - resourceBitmap.Height / 2); } // Brush to draw points with SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.Red.ToSKColor(), StrokeWidth = 5 }; // Draw every SKPoint in points foreach (SKPoint point in points) { canvas.DrawPoint(point, paint); } }
Oh, and saving it...
You can get an SKIMage from the surface and encode it:
SKImage image = surface.Snapshot(); SKData encodedImage = image.Encode(SKEncodedImageFormat.Png, 100);
And you can get a Stream from encodedImage and write your file.
Answers
Moved to SkiaSharp category
@hkidd
I should think so. Take a look at these guides:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/bitmaps
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/circle
Not sure what you want to draw over the image, but just do all of your drawing in the handler for the SKCanvasView.PaintSurface event handler, i.e. draw your bitmap image and then draw whatever else you want, circle, points, lines, more images, whatever. The following will draw an image and then any points that you have in
List<SKPoint> points
:Oh, and saving it...
You can get an SKIMage from the surface and encode it:
And you can get a Stream from encodedImage and write your file.