本文使用C++双缓存进行指定窗口截图。CreateDIBSection创建应用程序可以直接写入的、与设备无关的位图(DIB),它提供内存中位图的指针,外部程序可以直接使用。需要注意的是,BitBlt方
本文使用C++双缓存进行指定窗口截图。CreateDIBSection创建应用程序可以直接写入的、与设备无关的位图(DIB),它提供内存中位图的指针,外部程序可以直接使用。
需要注意的是,BitBlt方法只能抓图普通窗口的截图,对于使用D3D渲染的窗口(例如Excel、Win10自带视频播放器)则只能获取黑屏。
1、DibCaptureHelper.h
#pragmaonce#include#includeusingstd::string;classDibCaptureHelper{public:DibCaptureHelper();virtual~DibCaptureHelper();boolInit(conststring&windowName);boolInit(HWNDhwnd);voidCleanup();boolRefreshWindow();boolChangeWindowHandle(conststring&windowName);boolChangeWindowHandle(HWNDhwnd);boolCapture()const;constRECT&GetWindowRect()const{returnwindowRect_;}constRECT&GetClientRect()const{returnclientRect_;}intGetBitmapDataSize()const{returnbmpDataSize_;}HBITMAPGetBitmap()const{returnbitmap_;}void*GetBitmapAddress()const{returnbitsPtr_;}private:HWNDhwnd_;HDCscrDc_;HDCmemDc_;HBITMAPbitmap_;HBITMAPoldBitmap_;void*bitsPtr_;RECTwindowRect_;RECTclientRect_;POINTbitbltStartPoint_;intbmpDataSize_;};
2、DibCaptureHelper.cpp
#include\"stdafx.h\"#include\"DibCaptureHelper.h\"DibCaptureHelper::DibCaptureHelper():hwnd_(nullptr),scrDc_(nullptr),memDc_(nullptr),bitmap_(nullptr),oldBitmap_(nullptr),bitsPtr_(nullptr),windowRect_{0,0,0,0},clientRect_{0,0,0,0},bitbltStartPoint_{0,0},bmpDataSize_(0){}DibCaptureHelper::~DibCaptureHelper(){Cleanup();}boolDibCaptureHelper::Init(conststring&windowName){constautohandle=::FindWindowA(nullptr,windowName.c_str());if(handle==nullptr){returnfalse;}returnInit(handle);}boolDibCaptureHelper::Init(HWNDhwnd){hwnd_=hwnd;//获取窗口大小if(!::GetWindowRect(hwnd_,&windowRect_)||!::GetClientRect(hwnd_,&clientRect_)){returnfalse;}constautoclientRectWidth=clientRect_.right-clientRect_.left;constautoclientRectHeight=clientRect_.bottom-clientRect_.top;bmpDataSize_=clientRectWidth*clientRectHeight*4;bitbltStartPoint_.x=0;bitbltStartPoint_.y=0;//位图信息BITMAPINFObitmapInfo;bitmapInfo.bmiHeader.biSize=sizeof(bitmapInfo);bitmapInfo.bmiHeader.biWidth=clientRectWidth;bitmapInfo.bmiHeader.biHeight=clientRectHeight;bitmapInfo.bmiHeader.biPlanes=1;bitmapInfo.bmiHeader.biBitCount=32;bitmapInfo.bmiHeader.biSizeImage=clientRectWidth*clientRectHeight;bitmapInfo.bmiHeader.biCompression=BI_RGB;scrDc_=::GetWindowDC(hwnd_);//获取窗口DCmemDc_=::CreateCompatibleDC(scrDc_);//缓冲内存DCbitmap_=::CreateDIBSection(memDc_,&bitmapInfo,DIB_RGB_COLORS,&bitsPtr_,nullptr,0);if(bitmap_==nullptr){::DeleteDC(memDc_);::ReleaseDC(hwnd_,scrDc_);returnfalse;}oldBitmap_=static_cast(::SelectObject(memDc_,bitmap_));returntrue;}voidDibCaptureHelper::Cleanup(){if(bitmap_==nullptr){return;}//删除用过的对象::SelectObject(memDc_,oldBitmap_);::DeleteObject(bitmap_);::DeleteDC(memDc_);::ReleaseDC(hwnd_,scrDc_);hwnd_=nullptr;scrDc_=nullptr;memDc_=nullptr;bitmap_=nullptr;oldBitmap_=nullptr;bitsPtr_=nullptr;}boolDibCaptureHelper::RefreshWindow(){constautohwnd=hwnd_;Cleanup();returnInit(hwnd);}boolDibCaptureHelper::ChangeWindowHandle(conststring&windowName){Cleanup();returnInit(windowName);}boolDibCaptureHelper::ChangeWindowHandle(HWNDhwnd){Cleanup();returnInit(hwnd);}boolDibCaptureHelper::Capture()const{if(bitmap_==nullptr||memDc_==nullptr||scrDc_==nullptr){returnfalse;}constautoclientRectWidth=clientRect_.right-clientRect_.left;constautoclientRectHeight=clientRect_.bottom-clientRect_.top;constautoret=::BitBlt(memDc_,0,0,clientRectWidth,clientRectHeight,scrDc_,bitbltStartPoint_.x,bitbltStartPoint_.y,SRCCOPY);returnret!=0;}
总结
通过对C++使用BitBlt函数进行窗口抓图的详细解析,我们了解了整个抓图过程的步骤和关键点。BitBlt函数可以将一个设备上下文的内容复制到另一个设备上下文中,从而实现屏幕或窗口的抓图。本文提供的示例代码展示了如何在C++中使用BitBlt函数进行窗口抓图,并处理了一些常见的错误和异常情况。通过本文的学习,开发者可以掌握在C++中使用BitBlt函数进行窗口抓图的方法,提高图像处理的效率和质量。希望本文的内容能为读者在实际项目中提供有价值的参考和帮助。无论是处理用户界面的截图,还是实现自动化测试工具,本文的示例代码和方法都能为开发者提供有效的解决方案。
本站部分文章来自网络或用户投稿,如无特殊说明或标注,均为本站原创发布。涉及资源下载的,本站旨在共享仅供大家学习与参考,如您想商用请获取官网版权,如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。