Atzin
Atzin

Reputation: 125

How to fix 'Fatal Signal 11' when re-drawing onto SKCanvas

I'm trying to redraw a shape displayed on a SKCanvas the method (ChangeShape) works fine the 1st time it's called from the PaintSurface handler but when I attempt to call it again the app crashes and I receive the error "Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)".

I have tried to call the handler directly and Initialise a completely new SKSurface, but it still results in the same error.

public LinearLayout ImageDivisionLayout_Obj;
public SKCanvasView ImageViewActivity_Obj;
public SKSurface ImageCanvas;
public SKCanvas canvasSK;

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    SetContentView(Resource.Layout.activity_image);

    ImageViewActivity_Obj = new SKCanvasView(this);
    ImageViewActivity_Obj.PaintSurface += ImageViewActivity_Obj_PaintSurface;
    ImageDivisionLayout_Obj = (LinearLayout)FindViewById(Resource.Id.ImageLayoutDivision);
    ImageDivisionLayout_Obj.AddView(ImageViewActivity_Obj);
private void ImageViewActivity_Obj_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
    SKImageInfo info = e.Info;
    SKSurface surface = e.Surface;
    ImageCanvas = surface;
    SetupCanvas();
}

public void SetupCanvas()
{
    ShapePaint = new SKPaint();
    ShapePaint.Color = SKColor.Parse("#F00000");
    ShapePaint.StrokeWidth = 25;
    ShapePaint.Style = SKPaintStyle.Stroke;

    ImageCanvas.Canvas.DrawBitmap(
        AndroidExtensions.ToSKBitmap(ImageTaken),
        new SKRect(0, 0, ImageViewActivity_Obj.Width, 
        ImageViewActivity_Obj.Height));

    ChangeShape();

    ImageCanvas.Canvas.Save();
}

public void ChangeShape()
{
    float X1 = CurrentShape.X;
    float Y1 = CurrentShape.Y;
    float X2 = CurrentShape.X + CurrentShape.width;
    float Y2 = CurrentShape.Y + CurrentShape.height;

    if (CurrentShape.name == "Rectangle")
    {
        ImageCanvas.Canvas.DrawRect(X1, Y1, X2, Y2, ShapePaint);
    }
    else if (CurrentShape.name == "Circle")
    {
        ImageCanvas.Canvas.DrawCircle(new SKPoint(X2 - X1, Y2 - Y1), CurrentShape.width / 2, ShapePaint);
    }
}

Upvotes: 0

Views: 681

Answers (1)

Matthew
Matthew

Reputation: 5222

Having a look at what you are doing, I can see that this probably will not work on most platforms. The SKSurface that you are storing in the ImageCanvas field will be destroyed as soon as you leave the ImageViewActivity_Obj_PaintSurface method. The surface and canvas objects are transient and only live as long as the method is running.

I am assuming you are trying to create some sort of drawing app? If so, there are two approaches to this (although the smarter people may suggest more). You can either store all the operations in a list of some sort. Basically, if I draw a rectangle, store the operation and the bounds.

Or, you can create a background surface with SKSurface.Create(...) and then draw on that. When drawing to the screen, just copy the image from the background canvas to the screen canvas. Then, you can also just save the background canvas without trying to capture the screen canvas to save to disk.

I did a simple finger paint app here that you can check out for ideas: https://github.com/mattleibow/SkiaSharpDemo/blob/master/SkiaSharpDemo/SkiaSharpDemo/MainPage.xaml.cs

Upvotes: 1

Related Questions