捕获位图导致内存不足异常

时间:2016-01-15 13:43:50

标签: .net vb.net timer bitmap screenshot

问题

我目前正在尝试创建一个应用程序,用于创建用户屏幕的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())

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

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

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