我需要保存Xamarin.Forms WPF项目中的200个屏幕截图(制作视频)。
我在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);
}
}