一项目中需要不停对多个窗口进行截图,用了如下代码:
public static Image CaptureWindow(IntPtr handle)
{
IntPtr hdcSrc = User32.GetWindowDC(handle);
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
GDI32.SelectObject(hdcDest, hOld);
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
Image img = Image.FromHbitmap(hBitmap);
GDI32.DeleteObject(hBitmap);
return img;
}
发现每调用一次内存就增大根本不能释放掉,如果你调用几百次占用的内存让你无法忍受.请问题有什么办法解决.(我已经有种解决方法就时专门弄个截图的进程,内存到一定的数量的时候再重启进程,但这样操作起来就非常复杂了.)请不要说自己百度,或者GOOGLE都搜了没有这方面相关的东西.
求C#窗口截图不发生内存泄漏的代码
答案:5 悬赏:40 手机版
解决时间 2021-02-19 10:21
- 提问者网友:姑娘长的好罪过
- 2021-02-18 17:51
最佳答案
- 五星知识达人网友:第四晚心情
- 2021-02-18 18:46
IntPtr hscrdc = GetWindowDC(hWnd);
Control control = Control.FromHandle(hWnd);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
DeleteObject(SelectObject(hmemdc, hbitmap));//必须Delete否则内存泄漏
PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
DeleteDC(hmemdc);
ReleaseDC(hWnd, hscrdc);//Get要用Release释放
网上的造成泄漏的都是黑色标注部分的错误。
最后还要注意bmp用graphic.DrawImage复制一遍到新的Bitmap中,然后释放hbitmap,因为hbitmap是C++指针,必须用DeleteObject释放,否则也会造成内存泄漏。
Control control = Control.FromHandle(hWnd);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
DeleteObject(SelectObject(hmemdc, hbitmap));//必须Delete否则内存泄漏
PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
DeleteDC(hmemdc);
ReleaseDC(hWnd, hscrdc);//Get要用Release释放
网上的造成泄漏的都是黑色标注部分的错误。
最后还要注意bmp用graphic.DrawImage复制一遍到新的Bitmap中,然后释放hbitmap,因为hbitmap是C++指针,必须用DeleteObject释放,否则也会造成内存泄漏。
全部回答
- 1楼网友:爱难随人意
- 2021-02-18 21:20
把所有引用设为null,清空剪切板,gc.collection()
- 2楼网友:撞了怀
- 2021-02-18 20:55
携程一个类,截图的时候调用,用完使用析构函数手动释放不可以么?
再看看别人怎么说的。
- 3楼网友:行雁书
- 2021-02-18 20:16
不要写成静态方法,将方法内的变量抽出来。增加析构函数,在析构函数中将所有变量能调用Dispose();都调用一下,然后手工将值设置为null。最后加上
1
GC .Collect();
强制回收一下,如果不行请发整体代码上来,只能调试看一下是哪里的内存占用过高了。
- 4楼网友:低音帝王
- 2021-02-18 19:45
貌似都是封装的嘛
直接弄 C++ DLL调用看看
要求不高的话,或者使用 PrintWindow API看看
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯