Недостаточно памяти в Xamarin.Forms WPF при создании снимков экрана и сохранении в виде png

Мне нужно сохранить 200 снимков экрана (создание видео) из проекта Xamarin.Forms WPF.

Я написал следующее в проекте WPF, чтобы сделать скриншот и сохранить его в виде файла.png. Он работает нормально, но при съемке 200 последовательных снимков (небольшая задержка между кадрами) я получаю исключение "Недостаточно памяти". Я читал, что есть некоторые утечки памяти в растровых изображениях с Net Framework, но не знаю, где...

Я вызываю метод CaptureScreenShotAsync через службу зависимостей из проекта форм. Проект WPF ориентирован на.NetFramework 4.6.1

public void CaptureScreenShotAsync(float left, float right, float top, float bottom, string filePath)
{
    BitmapSource fullBmpSource;
    using (var screenBmp = new Bitmap(
        (int)SystemParameters.PrimaryScreenWidth,
        (int)SystemParameters.PrimaryScreenHeight,
        PixelFormat.Format32bppArgb))
    {
        using (var bmpGraphics = Graphics.FromImage(screenBmp))
        {
            bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
            fullBmpSource = Imaging.CreateBitmapSourceFromHBitmap(
                screenBmp.GetHbitmap(),
                IntPtr.Zero,
                Int32Rect.Empty,
                BitmapSizeOptions.FromEmptyOptions());
            fullBmpSource.Freeze();
        }
    }
    var fullWidth = fullBmpSource.PixelWidth;
    var fullHeight = fullBmpSource.PixelHeight;

    BitmapSource bmpSource;

    if (left.IsApproximatelyEqualTo(0f) && top.IsApproximatelyEqualTo(0f)
                                         && right.IsApproximatelyEqualTo(1f) && bottom.IsApproximatelyEqualTo(0f))
    {
        bmpSource = fullBmpSource;
    }
    else
    {
        var colStart = (int)(fullWidth * left);
        var colEnd = (int)(fullWidth * right);
        if ((colStart.IsEven() && colEnd.IsEven()) || (colStart.IsOdd() && colEnd.IsOdd()))
            colEnd = colEnd - 1;
        var rowStart = (int)(fullHeight * top);
        var rowEnd = (int)(fullHeight * bottom);
        if ((rowStart.IsEven() && rowEnd.IsEven()) || (rowStart.IsOdd() && rowEnd.IsOdd()))
            rowEnd = rowEnd - 1;
        var width = colEnd - colStart + 1;
        var height = rowEnd - rowStart + 1;
        bmpSource = new CroppedBitmap(fullBmpSource, new Int32Rect(colStart, rowStart, width, height));
        bmpSource.Freeze();
    }

    SaveBitmapAsFile(bmpSource, "PNG", filePath);

}

private static void SaveBitmapAsFile(BitmapSource bitmap, string format, string file)
{
    using (var fileStream = new FileStream(file, FileMode.Create))
    {
        BitmapEncoder encoder;
        switch (format)
        {
            case "BMP":
                encoder = new BmpBitmapEncoder();
                break;
            case "PNG":
                encoder = new PngBitmapEncoder();
                break;
            default:
                encoder = new PngBitmapEncoder();
                break;
        }
        encoder.Frames.Add(BitmapFrame.Create(bitmap));
        encoder.Save(fileStream);
    }
}

0 ответов

Другие вопросы по тегам