问题
我目前正在尝试创建一个应用程序,用于创建用户屏幕的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())
感谢任何帮助。
答案 0 :(得分:4)
这可能是很多非托管GDI句柄和位图数据保留在内存中。如果在25秒后你耗尽了可用的手柄,甚至只是可用的进程内存,我都不会感到惊讶。您可能需要考虑在记录时将每个帧保存到磁盘。然后在完成录制时,将各个图像处理为gif。
根据MSDN,进程可用的GDI句柄数可以在256到65536之间,具体取决于操作系统和配置。您正在使用的每个屏幕截图都使用至少一个句柄,并且您的应用程序和.net框架正在使用更多屏幕截图。