C# 快速制作屏幕截图,并且内存不足

C# 快速制作屏幕截图,并且内存不足,c#,.net,visual-studio,loops,bitmap,C#,.net,Visual Studio,Loops,Bitmap,我正在努力使我的屏幕截图非常快 所以,我在我的主类中使用这段代码 [STAThread] static void Main(string[] args) { int x = 1; int screenshotsAmount = 0; List<Bitmap> screenshots = new List<Bitmap>(); while (x == 1) { screenshots.Add(FullsizeScree

我正在努力使我的屏幕截图非常快

所以,我在我的主类中使用这段代码

[STAThread]
static void Main(string[] args)
{
    int x = 1;
    int screenshotsAmount = 0;
    List<Bitmap> screenshots = new List<Bitmap>();
    while (x == 1)
    {
        screenshots.Add(FullsizeScreenshot.makeScreenshot());
        Clipboard.SetImage(screenshots[screenshotsAmount]);
        Console.WriteLine("Screenshot " + screenshotsAmount + " has been made and added to the Bitmap list!");
        screenshotsAmount++;
    }
}
一切正常,但当屏幕截图数超过109时,我的程序会因System.ArgumentException崩溃

System.Drawing.dll中类型为“System.ArgumentException”的未处理异常 其他信息:无效参数

这句话的意思是: gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,Screen.PrimaryScreen.Bounds.Y,0,0,Screen.PrimaryScreen.Bounds.Size,CopyPixelOperation.SourceCopy); 或者这个: 位图截图=新位图(Screen.PrimaryScreen.Bounds.Width、Screen.PrimaryScreen.Bounds.Height、PixelFormat.Format32bppArgb)

我尝试使用(位图屏幕截图…)和.Dispose(),但它不能正常工作,因为这些类(位图和图形)都是类,它们只是创建链接而不是制作副本。因此,当我在makeScreenshot()中处理位图时,它会破坏列表中的位图


那么,我该怎么办?也许我应该复制一份,但我不知道怎么做。

假设你有一个1920x1080的显示器,也就是2073600像素,每像素有4个字节,像素格式是PixelFormat.Format32bppArgb,也就是8294400字节,大约8MB。109个图像将为872MB。令人惊讶的是,它在那里崩溃了,但你明白了,它的内存太多了


如果你想制作一个动画gif,想想它会有多大,全屏?嗯,我希望你没有打算这么做,这对gif来说是不现实的。拍摄屏幕截图后,立即将其调整到目标分辨率,以减少内存占用。

内存不足也就不足为奇了,在内存中存储数千个
位图
对象不是一个好主意。也许你应该改变你的要求…而不是千。我可以使用Thread.Sleep(100),但它仍然会崩溃,而这句话并不能说明什么sense@Jonesy他说如果他在while循环中加入Thread.Sleep(100),程序仍然会崩溃。这将减慢速度,使其每秒仅创建10个位图。据推测,崩溃只需不到100秒,因此程序在崩溃之前并没有“在内存中存储数千个位图对象”。崩溃前100个位图和1000个位图之间的区别是否重要可能是另一个问题。即使是100个屏幕截图也会占用相当多的内存。这取决于您正在使用的库,但使用带有网络摄像头的Forge只需10个左右的屏幕截图,而不进行处理,就会消耗内存(没有崩溃,但使用了120MB左右的内存)。关键是,运行足够长的时间,它将耗尽内存。你需要某种回收策略。我正在尝试制作GIF动画截图。但我得先拍很多截图。(大约每秒25-20个屏幕截图)如果是这样,只需将它们保存到文件\u number\u xx.png中即可。当你准备把它们编译成动画时,一次加载一个。是的,我现在就考虑过了。所以,我会努力的。但我正在考虑一些刷新的temp.jpeg,或者根据我的新评论尽快调整每个快照的大小。
// Class for making standard screenshots
public struct FullsizeScreenshot
{

    // Making fullscreen screenshot
    public static Bitmap makeScreenshot() 
    {
        Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

            Graphics gfxScreenshot = Graphics.FromImage(screenshot);

            gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

            gfxScreenshot.Dispose();

            return screenshot;
    }
}