★★ 关于抓屏的一个技术性问题 本人对 GDI 不熟悉,可目前又急需高效的抓屏方法,用 C + GDI 的就行, 请不要说写驱动或 DirectShow 之类的, BitBlt 这种常规方法的已经实现了,但希望找到一种速度更快的方法, 据说 GetDIBits、GetObject、GetCurrentObject 之类的某个函数可以直接从 屏幕 HDC 中取得 BITMAP,不知到该怎么写 大家帮帮忙,高分相赠。谢谢!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://community.csdn.net/Expert/topic/4867/4867627.xml?temp=.3163721http://community.csdn.net/Expert/topic/4867/4867625.xml?temp=.266659http://community.csdn.net/Expert/topic/4867/4867626.xml?temp=.2284204 blog.joycode.com/jiangsheng/ archive/2004/01/01/10410.aspx 需要截获显示器的显示内容,首先创建显示器的设备内容句柄,也就是在GetDC的时候传入一个NULL,而不是某个窗口的句柄,传入NULL可以获得整个当前屏幕的设备内容句柄。然后再准备一个内存位图和一个内存DC,把内存位图选入内存Dc,并且用Bitblt把整个屏幕的位图画到内存位图上,从而完成截图的过程。如果你需要一个简单的示例,可以发邮件给我。[email protected] HDC hScreen = GetDC(NULL); // 取得屏幕 DC能不能直接从这个 DC 中察看 BITMAP 中某些点的 RGB 数据? (不用 GetPixel)另外,谁知道 BitBlt 和 GetDIBits 的区别和效率有什么不同呢? 改用 CreateDIBSection、DIBSection 速度会有提高么? HDC hScreen = GetDC(NULL); // 取得屏幕 DCHBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP); // 取得屏幕DC装载的位图句柄BITMAPINFO bh = {0};bh.bmiHeader.biSize = sizeof(bh.bmiHeader);GetDIBits(hScreen, hBmp, 0, 0, NULL, &bh, DIB_RGB_COLORS); // 查询BITMAPINFO int nBitClrUsed = 0;if (bh.bmiHeader.biBitCount == 24) nBitClrUsed = 3; // 每个像素占用的字节数,以24位为例,其余色深自己判断BYTE * bits =new BYTE[bh.bmiHeader.biWidth * bh.bmiHeader.biHeight * nBitClrUsed];GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS); // 获得整张位图的数据,保存到bits指向的空间然后就可以按图像的坐标在bits中查找你要的像素的RGB信息了。BitBlt 是复制位图,GetDIBits 是取位图的位图数组。此外,有一个结论是,BitBlt将图像从屏幕拷到内存DC较慢,而用BitBlt将图像从内存DC拷到屏幕则相对快一些。 再精确下去,你其实就不要在GDI上下功夫了,提高效率也有限还是DShow来得快些。。 多谢羽兄我对 DirectX 更陌生,暂时没空研究了。请问 GetDIBits 比 BitBlt 能快多少呢?(我的目标不是完整的BMP,只要能得到 "RGB位图数组" 就可以了:)另外在 http://www.shenming.net/shen/oblog/user1/shenming/archives/2006/50.html中提到 DIBSection 要更快些,要从 Screen 获取 DIBSection 应该按怎样的顺序调用呢?我想从 BitBlt、GetDIBits、DIBsection 中选择一个最快的方法就可以了 pomelowu兄,上面的代码可以执行,我把他放在一个函数里 void TestRGB( void ){ HDC hDC = GetDC( NULL ); .......... .......... // 获取 bits 的代码,除了颜色位那里,其它未作任何修改 .......... GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS); // 监视此处 GetDIBits() 返回的扫描行是 768,正常! return; // 执行到 return 会抛出个异常, // 内存错误之类的,用 Debug 捕获不到}测试环境如下: XP Sp2, VS.Net 2005, Win32 Console Project [C++] 颜色: 16, 32 位模式分别测试==============================================================================另外 bh.bmiHeader.biBitCount 如果为 16 和 32,nBitClrUsed 应该是几呢?初学 GDI,见笑了... 执行到 return 会抛出个异常估计是写stack变量时越界,覆盖了返回地址。检查你对局部变量的写入操作。 void TestRGB( void ){ HDC hScreen = GetDC(NULL); HBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP); BITMAPINFO bh = {0}; bh.bmiHeader.biSize = sizeof(bh.bmiHeader); GetDIBits(hScreen, hBmp, 0, 0, NULL, &bh, DIB_RGB_COLORS); int nBitClrUsed = 0; if (bh.bmiHeader.biBitCount == 24) nBitClrUsed = 3; else if(bh.bmiHeader.biBitCount == 16) nBitClrUsed = 3; else if(bh.bmiHeader.biBitCount == 32) nBitClrUsed = 4; BYTE * bits =new BYTE[ bh.bmiHeader.biWidth * bh.bmiHeader.biHeight * nBitClrUsed ]; GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS); return;}这就是那个函数,有什么地方会操作了 stack 呢? if(bh.bmiHeader.biBitCount == 16) nBitClrUsed = 2;自己在单步调试的时候监视&hScreen之前的几个字节就可以看到 改成if(bh.bmiHeader.biBitCount == 16) nBitClrUsed = 2;...可问题依旧... 应该如何解决呢? 会有中文版本的MSDN的吗? 如何使用算法生成一段动画 在windows下,如何实现对本地某一socket连接的监视?? 【100分,继续问这个】内存释放的问题 为什么减我信誉分,给个理由先? 注册表中REG_LINK型数据的实质及其处理方式 关于网络一些问题的编程。 我知道注册Access的ODBC源如下,但不知道如何注册SqlServer的ODBC源,望各位指教 请问vc中怎么调用java写的com(简单) vc菜鸟关于组合框控件一问 windows下有没有可能把一个进程中的线程切换的信息记录下来啊 ★★ 高分求解
http://community.csdn.net/Expert/topic/4867/4867625.xml?temp=.266659
http://community.csdn.net/Expert/topic/4867/4867626.xml?temp=.2284204
HBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP);
// 取得屏幕DC装载的位图句柄BITMAPINFO bh = {0};
bh.bmiHeader.biSize = sizeof(bh.bmiHeader);
GetDIBits(hScreen, hBmp, 0, 0, NULL, &bh, DIB_RGB_COLORS); // 查询BITMAPINFO int nBitClrUsed = 0;
if (bh.bmiHeader.biBitCount == 24)
nBitClrUsed = 3; // 每个像素占用的字节数,以24位为例,其余色深自己判断
BYTE * bits =new BYTE[bh.bmiHeader.biWidth * bh.bmiHeader.biHeight * nBitClrUsed];
GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS);
// 获得整张位图的数据,保存到bits指向的空间然后就可以按图像的坐标在bits中查找你要的像素的RGB信息了。
BitBlt 是复制位图,GetDIBits 是取位图的位图数组。
此外,有一个结论是,BitBlt将图像从屏幕拷到内存DC较慢,而用BitBlt将图像从内存DC拷到屏幕则相对快一些。
我对 DirectX 更陌生,暂时没空研究了。请问 GetDIBits 比 BitBlt 能快多少呢?
(我的目标不是完整的BMP,只要能得到 "RGB位图数组" 就可以了:)另外在 http://www.shenming.net/shen/oblog/user1/shenming/archives/2006/50.html
中提到 DIBSection 要更快些,要从 Screen 获取 DIBSection 应该按怎样的顺序调用呢?我想从 BitBlt、GetDIBits、DIBsection 中选择一个最快的方法就可以了
pomelowu兄,上面的代码可以执行,我把他放在一个函数里
void TestRGB( void )
{
HDC hDC = GetDC( NULL );
..........
.......... // 获取 bits 的代码,除了颜色位那里,其它未作任何修改
..........
GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS);
// 监视此处 GetDIBits() 返回的扫描行是 768,正常! return; // 执行到 return 会抛出个异常,
// 内存错误之类的,用 Debug 捕获不到
}测试环境如下:
XP Sp2,
VS.Net 2005,
Win32 Console Project [C++]
颜色: 16, 32 位模式分别测试
==============================================================================另外 bh.bmiHeader.biBitCount 如果为 16 和 32,nBitClrUsed 应该是几呢?
初学 GDI,见笑了...
{
HDC hScreen = GetDC(NULL);
HBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP); BITMAPINFO bh = {0};
bh.bmiHeader.biSize = sizeof(bh.bmiHeader);
GetDIBits(hScreen, hBmp, 0, 0, NULL, &bh, DIB_RGB_COLORS); int nBitClrUsed = 0;
if (bh.bmiHeader.biBitCount == 24)
nBitClrUsed = 3;
else if(bh.bmiHeader.biBitCount == 16)
nBitClrUsed = 3;
else if(bh.bmiHeader.biBitCount == 32)
nBitClrUsed = 4; BYTE * bits =new BYTE[ bh.bmiHeader.biWidth * bh.bmiHeader.biHeight * nBitClrUsed ];
GetDIBits(hScreen, hBmp, 0, bh.bmiHeader.biHeight, bits, &bh, DIB_RGB_COLORS); return;
}这就是那个函数,有什么地方会操作了 stack 呢?
nBitClrUsed = 2;自己在单步调试的时候监视&hScreen之前的几个字节就可以看到
nBitClrUsed = 2;
...可问题依旧... 应该如何解决呢?