【问题标题】:Generic GDI+ Error通用 GDI+ 错误
【发布时间】:2011-04-29 00:37:44
【问题描述】:

我得到以下代码的通用 GDI 错误。通常它符合并执行得很好,但有时会因通用 GDI+ 错误而失败。有没有办法解决这个问题,或者不使用互操作来截取屏幕截图?

Public Function CopyImageFromScreen(region as Int32Rect) As BitmapSource

    Dim img As New System.Drawing.Bitmap(region.Width, region.Height)
    Dim gfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(img)
    gfx.CopyFromScreen(region.X, region.Y, 0, 0, New System.Drawing.Size(region.Width, region.Height))
    img.LockBits(New System.Drawing.Rectangle(0, 0, img.Width, img.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, img.PixelFormat)

    Dim hObject As IntPtr = img.GetHbitmap 'This Line Causes the Error

    Dim WpfImage As BitmapSource = Interop.Imaging.CreateBitmapSourceFromHBitmap(hObject, IntPtr.Zero, _
        System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions())

    Return WpfImage

End Function

【问题讨论】:

    标签: .net wpf vb.net gdi+


    【解决方案1】:

    这可能有帮助,也可能没有帮助,但据我所知,您并没有清理此方法中分配的任何资源。即使这没有帮助,最好的做法也是清理一次性对象并且不依赖 GC。

    也就是说,.NET 框架中的“经典”图像支持(即 System.Drawing.Image)主要是对原生 GDI/GDI+ 库的封装,并且容易泄漏非托管资源。

    我的建议是将imggfx 对象包装在using 块中,并通过对DeleteObject 的互操作调用显式删除hObject 句柄,并包含在try/finally 块中以防CreateBitmapSourceFromHBitmap 失败。

    ...为什么框架在 Image 类上提供了 GetHbitmap 方法,但没有在没有互操作代码的情况下删除它的方法是一个谜。查看 GetHbitmap 上的 MSDN 文档了解更多详细信息。

    【讨论】:

    • 我检查了代码确实是内存泄漏,现在已修复。 CreateBitmapSourceFromHBitmap 仍然会定期失败。我实现了 Try/Catch 块,所以它按照你的建议优雅地失败了。感谢您的帮助。
    • @PeterM 如果您仅重试 CreateBitmap 操作,它会成功还是必须再次运行整个例程?
    猜你喜欢
    • 2011-01-11
    • 2012-06-27
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2012-08-25
    • 2017-08-03
    • 1970-01-01
    相关资源
    最近更新 更多