Forum Libraries, Components, and Plugins

Set CanvasView from new canvas

Hi everyone !

I'm trying to set my SKCanvasView with a picture that I get this way :

        var pictureBytes = await picManager.GetImagBytes("Photo_7313c011-ce59-42b9-849d-acd7d2046b08");
        var bitmap = SKBitmap.Decode(SKData.CreateCopy(pictureBytes));
        this.canvasView = new SKCanvas(bitmap); <- giving me an error 

The error says that "Cannot implicitly convert type 'SkiaSharp.SKCanvas' to 'SkiaSharp.Views.Forms.SKCanvasView' which makes sense.

The problem is that I can't find a way to define the canvas of this canvasView.
Would anyone have an idea on how to do that ?

Thanks !

Best Answer

  • mattleibowmattleibow ZAXamarin Team Xamurai
    edited June 2017 Accepted Answer

    You don't define the canvas, the view does.

    If you want to draw on the canvas, then you subscribe to the PaintSurface event:
    https://developer.xamarin.com/api/event/SkiaSharp.Views.Forms.SKCanvasView.PaintSurface/

    this.canvasView.PaintSurface += (sender, e) => {
        var surface = e.Surface;
        var surfaceSize = e.Info.Size;
    
        // get the canvas from the view
        var canvas = surface.Canvas;
    
        // draw the bitmap on the canvas
        canvas.DrawBitmap(bitmap, 0, 0);
    
        // draw other stuff
    };
    

    The reason for this is that the OS actually determines, and manages, the canvas for drawing on the UI. At the end of the paint event, the canvas is destroyed - so you must not track that either.

Answers

  • mattleibowmattleibow ZAXamarin Team Xamurai
    edited June 2017 Accepted Answer

    You don't define the canvas, the view does.

    If you want to draw on the canvas, then you subscribe to the PaintSurface event:
    https://developer.xamarin.com/api/event/SkiaSharp.Views.Forms.SKCanvasView.PaintSurface/

    this.canvasView.PaintSurface += (sender, e) => {
        var surface = e.Surface;
        var surfaceSize = e.Info.Size;
    
        // get the canvas from the view
        var canvas = surface.Canvas;
    
        // draw the bitmap on the canvas
        canvas.DrawBitmap(bitmap, 0, 0);
    
        // draw other stuff
    };
    

    The reason for this is that the OS actually determines, and manages, the canvas for drawing on the UI. At the end of the paint event, the canvas is destroyed - so you must not track that either.

  • mattleibowmattleibow ZAXamarin Team Xamurai
    edited June 2017

    If you just want to display an image, it may be best to just use the built-in image control <Image />, if you need to do something with SkiaSharp for some reason (once-off), you can use the image source:

    // the SkiaSharp image
    SKBitmap bitmap = ...;
    
    // the Forms image view
    Image imageView = ...;
    
    // set the source
    imageView.Source = bitmap;
    

    Note, you will not receive any events, and if you draw on the bitmap, nothing will appear on the image view.

  • PierreParmPierreParm FRMember ✭✭
    edited June 2017

    Thank you for the quick and complete answer.
    I'm trying to draw on the image indeed.

    I'll mark the answer as the solution as soon as I get it working !

    For now, I'm getting a 'System.AccessViolationException' when trying the simple
    var canvas = args.Surface.Canvas;

  • PierreParmPierreParm FRMember ✭✭

    I'm sorry for the double post.

    I'm acquiring my bitmap the way I showed in my first post :
    var pictureBytes = await picManager.GetImagBytes("Photo_7313c011-ce59-42b9-849d-acd7d2046b08"); var bitmap = SKBitmap.Decode(SKData.CreateCopy(pictureBytes));

    Do I need something else to be able to draw it ?
    Everything seems good to me this way but I still get the access violation exception on the canvas when calling drawBitmap.

  • mattleibowmattleibow ZAXamarin Team Xamurai

    That should be OK. Are you storing the args in a variable somewhere? The args are only valid inside the paint event - and no async can be used in there either. You will have to first load the bitmap, and then once loaded draw it. As the paint event is a UI operation, it cannot wait for another thread to complete - it will always complete immediately.

  • hkiddhkidd Member ✭✭

    Hi! I am trying to draw on an image that is passed into my fingerpainting class. Is there a way to set the canvas or the paintsurface in the SKCanvasView so that I can see the annotations being drawn on my image? @mattleibow @PierreParm

Sign In or Register to comment.