【问题标题】:Making screenshots very fast and out of memory使屏幕截图非常快且内存不足
【发布时间】:2014-10-27 02:41:08
【问题描述】:

我正在尝试快速截取屏幕截图。

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

[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++;
    }
}

我的 .dll 中有一个创建屏幕截图的方法

// 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;
    }
}

一切正常,但是当屏幕截图数量大于 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); 或这个: 位图截图 = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

我尝试使用 using (Bitmap screenshot....) 和 .Dispose(),但它不能正常工作,因为这些类(Bitmap 和 Graphics)是类,它们只是创建链接而不是制作副本。结果,当我在 makeScreenshot() 中处理位图时,它破坏了列表中的位图。

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

【问题讨论】:

  • 内存不足并不奇怪,在内存中存储数以千计的Bitmap 对象并不是一个好主意。也许你应该改变你的要求......
  • 不是千。我可以使用 Thread.Sleep(100) 仍然会崩溃
  • 那句话没有意义
  • @Jonesy 他的意思是如果他把 Thread.Sleep(100) 放在 while 循环中,程序仍然会崩溃。这会减慢它的速度,使其每秒只创建十个位图。据推测,崩溃所需的时间不到 100 秒,因此程序在崩溃之前并不是“将数千个 Bitmap 对象存储在内存中”。崩溃前 100 位图和 1000 位图之间的区别是否重要可能是另一回事。
  • 即使是 100 张截图也会占用相当多的内存。这取决于您使用的是什么库,但是使用 AForge 和网络摄像头仅 10 个左右的屏幕截图而不进行处理会占用内存(没有崩溃,但使用了 120MB 左右的内存)。重点是,运行它足够长的时间,它耗尽内存。您需要制定某种回收策略。

标签: c# .net visual-studio loops bitmap


【解决方案1】:

假设您有一个 1920x1080 的显示器,即 2,073,600 像素,PixelFormat.Format32bppArgb 中每个像素有 4 个字节,所以这是 8,294,400 字节,或大约 8 MB。 109 张图片为 872 MB。很惊讶它会在那里崩溃,但你明白了,它的内存太多了。

如果您想制作动画 gif,请考虑一下它将有多大,全屏?好吧,我希望您不要计划这样做,这对于 gif 来说是不切实际的。截取屏幕截图后,立即将其大小调整为目标分辨率,以减少内存占用。

【讨论】:

  • 我正在尝试制作 GIF 动画截图。但是我必须先制作很多截图。 (大约每秒 25-20 张截图)
  • 如果是这种情况,只需将它们保存到 file_number_xx.png。当你准备好将它们编译成动画时,一次加载一个。
  • 是的,我现在就想到了。所以,我会尝试。但我正在考虑某种令人耳目一新的 temp.JPEG
  • 或者根据我的新 cmets 尽快缩小每个镜头的大小。
猜你喜欢
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
相关资源
最近更新 更多