首页 > 解决方案 > 重新绘制到 SKCanvas 时如何修复“致命信号 11”

问题描述

我正在尝试重绘显示在 SKCanvas 上的形状,该方法 (ChangeShape) 第一次从 PaintSurface 处理程序调用时工作正常,但是当我尝试再次调用它时,应用程序崩溃并且我收到错误“致命信号 11 (SIGSEGV ),代码 1 (SEGV_MAPERR)”。

我试图直接调用处理程序并初始化一个全新的 SKSurface,但它仍然会导致相同的错误。

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);
    }
}

标签: c#xamarin.androidskiasharp

解决方案


看看你在做什么,我可以看到这可能不适用于大多数平台。离开该方法后,您存储在该字段中的内容将立即被销毁SKSurface。表面和画布对象是瞬态的,并且仅在方法运行时才存在。ImageCanvasImageViewActivity_Obj_PaintSurface

我假设您正在尝试创建某种绘图应用程序?如果是这样,有两种方法可以解决这个问题(尽管更聪明的人可能会提出更多建议)。您可以将所有操作存储在某种列表中。基本上,如果我画一个矩形,存储操作和边界。

或者,您可以创建一个背景表面,SKSurface.Create(...)然后在其上绘制。绘制到屏幕时,只需将图像从背景画布复制到屏幕画布即可。然后,您也可以只保存背景画布,而无需尝试捕获屏幕画布以保存到磁盘。

我在这里做了一个简单的手指画应用程序,您可以查看它的想法:https ://github.com/mattleibow/SkiaSharpDemo/blob/master/SkiaSharpDemo/SkiaSharpDemo/MainPage.xaml.cs


推荐阅读