Недостаточно памяти в 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);
}
}