skiasharp xamarin.form memory release

木幡 弘文 1 Reputation point
2021-10-16T13:07:32.727+00:00

I'm using skiasharp to display multiple images, but the app crashes over time.

I think it's a memory usage issue.

Is there a problem with the code below?

public async void Pic()
{

    try
    {

        int nY;
        int nX;

        MAX = 0;
        BX = 0;
        EX = 0;
        BY = 0;
        EY = 0;
        offX = 0;
        offY = 0;
        nX = 0;
        nY = 0;
        zoomOver = 0;

        int ZoomSub = Zoom;

        MAX = (int)Math.Pow(2, ZoomSub) - 1;
        BX = Math.Max(0, (CX - W / 2) / 256);
        EX = Math.Min(MAX, (CX + W / 2 + 255) / 256);
        BY = Math.Max(0, (CY - H / 2) / 256);
        EY = Math.Min(MAX, (CY + H / 2 + 255) / 256);
        offX = (CX - W / 2) % 256;
        offY = (CY - H / 2) % 256;

        bitmaps.Clear();

        Assembly assembly = GetType().GetTypeInfo().Assembly;

        string spath = "";

        HttpClient httpClient = new HttpClient();

        for (nY = BY; nY <= EY; nY++)
        {
            for (nX = BX; nX <= EX; nX++)
            {
                string url = "";
                string imgpath = "";

                SKBitmap img = SKBitmap.Decode("App.pic.noimage.png");

                //img = SKBitmap.Decode("App.pic.noimage.png");

                if ((System.IO.File.Exists(imgpath) == false) || (SKBitmap.Decode(imgpath) == null))
                {

                    try
                    {

                        if (zoomOver > 0)
                        {
                            //spath = fileDL(url, MapPath + (Zoom - zoomOver) + "/" + (nX / (zoomOver * 2)) + "/");

                            switch (omapmode)
                            {
                                case 1:
                                    spath = fileDL(url, MapPath + "std/" + (Zoom - zoomOver) + "/" + nX + "/");
                                    break;
                                case 2:
                                    spath = fileDL(url, MapPath + "seamlessphoto/" + (Zoom - zoomOver) + "/" + nX + "/");
                                    break;
                                case 3:
                                    spath = fileDL(url, MapPath + "pale/" + (Zoom - zoomOver) + "/" + nX + "/");
                                    break;
                                default:
                                    spath = fileDL(url, MapPath + "openstreetmap/" + (Zoom - zoomOver) + "/" + nX + "/");
                                    break;
                            }

                        }
                        else
                        {
                            //spath = fileDL(url, MapPath + Zoom + "/" + nX + "/");

                            switch (omapmode)
                            {
                                case 1:
                                    spath = fileDL(url, MapPath + "std/" + Zoom + "/" + nX + "/");
                                    break;
                                case 2:
                                    spath = fileDL(url, MapPath + "seamlessphoto/" + Zoom + "/" + nX + "/");
                                    break;
                                case 3:
                                    spath = fileDL(url, MapPath + "pale/" + Zoom + "/" + nX + "/");
                                    break;
                                default:
                                    spath = fileDL(url, MapPath + "openstreetmap/" + Zoom + "/" + nX + "/");
                                    break;
                            }
                        }

                        using (Stream stream = await httpClient.GetStreamAsync(url))
                        using (MemoryStream memStream = new MemoryStream())
                        {

                            if (dictTiles.Contains(imgpath))
                            {
                                img = (SKBitmap)dictTiles[imgpath];
                            }
                            else
                            {
                                await stream.CopyToAsync(memStream);
                                memStream.Seek(0, SeekOrigin.Begin);

                                if (dictTiles.Count > DictSize)
                                {
                                    dictTiles.RemoveAt(0);
                                }

                                dictTiles[imgpath] = SKBitmap.Decode(memStream);
                                img = (SKBitmap)dictTiles[imgpath];
                            }


                        }

                    }
                    catch (Exception)
                    {
                    }

                }

                int iX = (nX) % tilecnt;
                int iY = (nY) % tilecnt;
                SKBitmap imgset = new SKBitmap(img.Width, img.Height);
                SKRect dest = new SKRect(0, 0, img.Width, img.Height);
                float x0 = iX * (img.Width / tilecnt);
                float y0 = iY * (img.Height / tilecnt);
                float x1 = x0 + (img.Width / tilecnt);
                float y1 = y0 + (img.Height / tilecnt);
                SKRect src = new SKRect(x0, y0, x1, y1);

                using (SKCanvas canvas = new SKCanvas(imgset))
                {
                    canvas.DrawBitmap(img, src, dest);
                    bitmaps.Add(imgset);

                }

            }

        }


        yy = Math.Abs(EY - BY);
        xx = Math.Abs(EX - BX);

        httpClient.Dispose();
    }
    catch (Exception)
    {
    }

}

private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    try
    {
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;

        canvas.Clear();

        int imgsize = 256;
        int i = 0;
        for (int y = 0; y <= yy; y++)
        {
            for (int x = 0; x <= xx; x++)
            {
                canvas.DrawBitmap(bitmaps[i], imgsize * x - offX, imgsize * y - offY, null);

                i++;
            }
        }

        canvas.DrawCircle(x0, y0, swidth, paint);

        canvas.Dispose();
    }
    catch
    {

    }
}
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,371 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.