本文使用C++双缓存进行指定窗口截图。CreateDIBSection创建应用程序可以直接写入的、与设备无关的位图(DIB),它提供内存中位图的指针,外部程序可以直接使用。
需要注意的是,BitBlt方法只能抓图普通窗口的截图,对于使用D3D渲染的窗口(例如Excel、Win10自带视频播放器)则只能获取黑屏。
1、DibCaptureHelper.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #pragma once #include <windows.h> #include <string> using std::string; class DibCaptureHelper { public : DibCaptureHelper(); virtual ~DibCaptureHelper(); bool Init( const string& windowName); bool Init( HWND hwnd); void Cleanup(); bool RefreshWindow(); bool ChangeWindowHandle( const string& windowName); bool ChangeWindowHandle( HWND hwnd); bool Capture() const ; const RECT& GetWindowRect() const { return windowRect_; } const RECT& GetClientRect() const { return clientRect_; } int GetBitmapDataSize() const { return bmpDataSize_; } HBITMAP GetBitmap() const { return bitmap_; } void * GetBitmapAddress() const { return bitsPtr_; } private : HWND hwnd_; HDC scrDc_; HDC memDc_; HBITMAP bitmap_; HBITMAP oldBitmap_; void * bitsPtr_; RECT windowRect_; RECT clientRect_; POINT bitbltStartPoint_; int bmpDataSize_; }; |
2、DibCaptureHelper.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #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(); } bool DibCaptureHelper::Init( const string& windowName) { const auto handle = ::FindWindowA(nullptr, windowName.c_str()); if (handle == nullptr) { return false ; } return Init(handle); } bool DibCaptureHelper::Init( HWND hwnd) { hwnd_ = hwnd; //获取窗口大小 if (!::GetWindowRect(hwnd_, &windowRect_) || !::GetClientRect(hwnd_, &clientRect_)) { return false ; } const auto clientRectWidth = clientRect_.right - clientRect_.left; const auto clientRectHeight = clientRect_.bottom - clientRect_.top; bmpDataSize_ = clientRectWidth * clientRectHeight * 4; bitbltStartPoint_.x = 0; bitbltStartPoint_.y = 0; //位图信息 BITMAPINFO bitmapInfo; 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_); //获取窗口DC memDc_ = ::CreateCompatibleDC(scrDc_); //缓冲内存DC bitmap_ = ::CreateDIBSection(memDc_, &bitmapInfo, DIB_RGB_COLORS, &bitsPtr_, nullptr, 0); if (bitmap_ == nullptr) { ::DeleteDC(memDc_); ::ReleaseDC(hwnd_, scrDc_); return false ; } oldBitmap_ = static_cast < HBITMAP >(::SelectObject(memDc_, bitmap_)); return true ; } void DibCaptureHelper::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; } bool DibCaptureHelper::RefreshWindow() { const auto hwnd = hwnd_; Cleanup(); return Init(hwnd); } bool DibCaptureHelper::ChangeWindowHandle( const string& windowName) { Cleanup(); return Init(windowName); } bool DibCaptureHelper::ChangeWindowHandle( HWND hwnd) { Cleanup(); return Init(hwnd); } bool DibCaptureHelper::Capture() const { if (bitmap_ == nullptr || memDc_ == nullptr || scrDc_ == nullptr) { return false ; } const auto clientRectWidth = clientRect_.right - clientRect_.left; const auto clientRectHeight = clientRect_.bottom - clientRect_.top; const auto ret = ::BitBlt( memDc_, 0, 0, clientRectWidth, clientRectHeight, scrDc_, bitbltStartPoint_.x, bitbltStartPoint_.y, SRCCOPY); return ret != 0; } |
以上就是C++使用BitBlt进行窗口抓图的方法的详细内容,更多关于c++ 窗口抓图的资料请关注自学编程网其它相关文章!
- 本文固定链接: https://zxbcw.cn/post/203633/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)