【问题标题】:Capturing bitmaps causing Out Of Memory exception捕获导致内存不足异常的位图
【发布时间】:2016-04-21 03:04:32
【问题描述】:

问题

我目前正在尝试创建一个应用程序,该应用程序将在用户在计算机上复制问题时创建用户屏幕的 gif/视频(尚未确定)。这显然意味着我需要通过计时器定期创建屏幕截图。

问题是 25 秒后(总是 25 秒),我收到一条错误消息,提示系统内存不足。

Exception thrown: 'System.OutOfMemoryException' in System.Drawing.dll

Additional information: Out of memory.

我的代码

下面是 Timer Tick 事件中的代码:

Private DebugVid As New List(Of IntPtr)

Private Sub tmrDebug_Tick(sender As Object, e As EventArgs) Handles tmrDebug.Tick

    Dim CurrentScreen As Screen = Screen.PrimaryScreen
    For Each SCR As Screen In Screen.AllScreens
        If SCR.Bounds.Contains(MousePosition) Then
            CurrentScreen = SCR
        End If
    Next

    Using ScreenGrab As New Bitmap(CurrentScreen.Bounds.Width, CurrentScreen.Bounds.Height)
        Using g As Graphics = Graphics.FromImage(ScreenGrab)
            g.CopyFromScreen(New Point(CurrentScreen.Bounds.X, CurrentScreen.Bounds.Y), New Point(0, 0), ScreenGrab.Size)
            g.DrawImage(My.Resources.MyCursor, New Point(MousePosition.X - CurrentScreen.Bounds.X, MousePosition.Y))
        End Using
        DebugVid.Add(ScreenGrab.GetHbitmap())
    End Using

    GC.Collect()
End Sub

第一部分只是定义了光标在哪个屏幕上,所以我知道要在哪个屏幕上创建位图。

第二部分创建位图,对其应用屏幕截图,在鼠标位置绘制光标,最后将整数指针存储在列表中。

一旦用户单击按钮停止录制,它就会将其转换为 gif(此时)。

引发异常的部分代码如下:

DebugVid.Add(ScreenGrab.GetHbitmap())

感谢任何帮助。

【问题讨论】:

  • 25 秒,每秒多少帧?图片尺寸是多少?做数学,你可能会明白为什么你的内存不足。您最好将文件保存在某个地方并用它们构建 GIF,只是不要将它们保存在内存中。顺便说一句,你为什么需要 HBITMAP?
  • 这是我第一次尝试这样的事情,所以我有来自网络各地的点点滴滴,因此是 HBITMAP。我确实知道存储图像是一项艰巨的任务,因此我目前正在尝试的任何替代方法都非常受欢迎。计时器每秒运行两次,图像大小是我的屏幕分辨率,目前是 1680x1050

标签: .net vb.net timer bitmap screenshot


【解决方案1】:

这可能有很多非托管 GDI 句柄和位图数据要保存在内存中。如果你在 25 秒后耗尽了可用的句柄,甚至只是可用的进程内存,我一点也不会感到惊讶。您可能需要考虑在记录时将每个帧保存到磁盘。然后在录制完成后,将单个图像处理为 gif。

根据MSDN,一个进程可用的 GDI 句柄的数量可以在 256 到 65536 之间,具体取决于操作系统和配置。您拍摄的每个屏幕截图都使用了至少一个句柄,并且您的应用程序和 .net 框架正在使用更多的句柄。

【讨论】:

  • 我实际上只是尝试了您的建议,并将屏幕截图的 Base 64 字符串版本保存在文本文件中,而不是将其存储在内存中。该文件在大约一分半钟内达到 8GB,因此不完全可行。有没有更好的存储方式?
  • Base 64 编码实际上会使您的文件更大。我建议将每一帧保存为png。它应该为您提供显着的压缩而不会降低质量。此外,在 8GB 磁盘上,这当然可以解释为什么您的内存不足。
  • 大约 100MB 在 1 分钟内,我认为这是我将得到的最好的,非常感谢。我只需要记住在创建 GIF 时删除 PNG!
猜你喜欢
  • 2013-12-09
  • 2014-08-26
  • 2011-07-16
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
相关资源
最近更新 更多