如何获取位图的缩略图?

Wafly 2009-05-11 01:11:04
想编一个截取窗口内容的程序,但是创建位图时总是出错(应该是内存不足的原因吧)
下面是代码:

CRect rcClient = NULL;
GetWindowRect(hwnd,&rcClient); //hwnd是目标窗口句柄
int w = rcClient.right - rcClient.left;
int h = rcClient.bottom - rcClient.top;

HDC dc = GetDC(hwnd);

HDC gpBmpHdc = CreateCompatibleDC(dc);
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h); //这一句出错

HGDIOBJ oldhdc = SelectObject(gpBmpHdc, hBitmap);

PrintWindow(hwnd,gpBmpHdc,NULL);

CImage image;
image.Attach(hBitmap);
image.Save(L"c:\\B.bmp");
image.Detach();

DeleteDC(gpBmpHdc);
ReleaseDC(hwnd, dc);
DeleteObject(oldhdc);
DeleteObject(hBitmap);
这段代码截取小尺寸的窗口(QQ窗口、计算器……)还行,最大化窗口就不行了

我只是想取得的图片能看清就行,所以就想到能不能从DC中取得小图,这样就不会导致内存不足了
小弟初学c++,不知道有高手知道这个想法可行么
...全文
251 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Wafly 2009-05-12
  • 打赏
  • 举报
回复
我还试着用HeapAlloc()调整内存,甚至直接在链接器中设置内存大小,好像都没有效果……唉……
Wafly 2009-05-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 chris820313 的回复:]
刚才又测试了一下,用FindWindow来获取其他窗口的句柄,传到hwnd里面,运行也没问题。不行重做系统或者重新装VS吧,别跟它较劲了。我这就没什么问题,单纯的运行你所需要的功能的话
[/Quote]

中午用自己的机子调试了一下,也没问题

果然还是内存不足的原因吧……公司的机子做代理服务器,还运行了大量程序,内存剩下不到100M,所以截下1280*1024的窗口就会报错。

以上是我自己的推测,也不知道对不对……毕竟刚刚接触C++,很多盲点……如果是这样的话,就像一开始说的,能不能只创建一个“小图”呢?毕竟这程序还是得在公司的机子上跑的
  • 打赏
  • 举报
回复
刚才又测试了一下,用FindWindow来获取其他窗口的句柄,传到hwnd里面,运行也没问题。不行重做系统或者重新装VS吧,别跟它较劲了。我这就没什么问题,单纯的运行你所需要的功能的话
  • 打赏
  • 举报
回复
也就是说dc也是空的了…………
从HDC dc = GetDC(hwnd);开始就出现调用出错,方便的话代码发过来看看吧,我个人怀疑是hwnd的问题

我自己创建了一个对话框,在OnOK响应函数中添加了你的代码,运行没有什么问题

CRect rcClient = NULL;
HWND hwnd=this->GetSafeHwnd(); //令HWND为本窗口的句柄
::GetWindowRect(hwnd,&rcClient);
int w = rcClient.right - rcClient.left;
int h = rcClient.bottom - rcClient.top;

HDC dc = ::GetDC(hwnd);

HDC gpBmpHdc = CreateCompatibleDC(dc);
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h); //这一句出错

HGDIOBJ oldhdc = SelectObject(gpBmpHdc, hBitmap);

::PrintWindow(hwnd,gpBmpHdc,NULL);

CImage image;
image.Attach(hBitmap);
image.Save(L"c:\\B.bmp");
image.Detach();

DeleteDC(gpBmpHdc);
::ReleaseDC(hwnd, dc);
DeleteObject(oldhdc);
DeleteObject(hBitmap);
OnOK();
Wafly 2009-05-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 chris820313 的回复:]
这样的话你只要仔细检查一下你代码的【各个部分】,看看是否有地方建立了GDI对象等占用内存的东西但是却没有被正常销毁
[/Quote]

还是不行啊……我的程序很简单,只有这一处使用GDI
还有我将GetLasterror()移动到
HDC dc = GetDC(hwnd);
一句的后面时就总会报“传递给系统调用的数据区域太小”
  • 打赏
  • 举报
回复
这样的话你只要仔细检查一下你代码的【各个部分】,看看是否有地方建立了GDI对象等占用内存的东西但是却没有被正常销毁
Wafly 2009-05-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 chris820313 的回复:]
ATLimage.h 行504 是关于CImage::Attach函数的一个断言
ATLASSERT( hBitmap != NULL );

也就是说,在Attach被调用前,应该首先保证hBitmap参数真实有效。
该参数的无效源于
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h);调用的失败,导致hBitmap句柄为空,所以CImage::Attach断言失败,造成程序出错。

你可以使用GetLasterror();并配合FormatMessage函数来查看究竟出现了什么错误

LPVOID lpMsgBuf;

[/Quote]


我把你的代码加到了
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h);
这一句的下面,结果对话框显示“存储空间不足,无法处理此命令”
有办法解决么?
Wafly 2009-05-12
  • 打赏
  • 举报
回复
不行,还是在启动时检测GDI数是否符合要求好了……
Wafly 2009-05-12
  • 打赏
  • 举报
回复
不要放弃不要放弃~……哈哈,终于被我找到原因了
是因为飞秋占用了太多的系统GDI对象(1千多……这个垃圾不释放DC)
把飞秋关闭后一切正常~~
现在问题就到了“如何抢占其它程序的GDI”了
不知道这个有没有可能呢
  • 打赏
  • 举报
回复
认了吧,这种奇怪的错误多了,我有个程序在自己机器上跑一释放内存就崩溃,在别人那跑什么问题都没有,我同事笑称我机器太牛逼了,内存很多,不让我释放,说释放是侮辱它,所以崩溃
  • 打赏
  • 举报
回复
ATLimage.h 行504 是关于CImage::Attach函数的一个断言
ATLASSERT( hBitmap != NULL );

也就是说,在Attach被调用前,应该首先保证hBitmap参数真实有效。
该参数的无效源于
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h);调用的失败,导致hBitmap句柄为空,所以CImage::Attach断言失败,造成程序出错。

你可以使用GetLasterror();并配合FormatMessage函数来查看究竟出现了什么错误

LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
MessageBox( NULL, (LPCTSTR)lpMsgBuf, LError, MB_OK | MB_ICONINFORMATION );
LocalFree( lpMsgBuf );
上面的代码将GetLasterror()得到的错误以对话框的方式弹出,看看错误描述,在查阅MSDN有关CreateCompatibleBitmap的描述。

Wafly 2009-05-11
  • 打赏
  • 举报
回复
我也不太清楚,只是会弹出一个对话框(字很多的说……),内容大概是:

Debug Assertion Failed!
Program:e:\我的文档\……\include\atlimage.h
Line:504

Expression:hBitmap != 0 (这里的hBitmap就是出错的那句的变量)

For information on ……(意思大概是“想知道原因就去看C++的文档”)

(Press Retry to debug the application)

以上
  • 打赏
  • 举报
回复
HBITMAP hBitmap = CreateCompatibleBitmap(dc, w, h); //这一句出错
出错是什么意思?程序崩溃?编译不过?

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧