1GDI- bitblt方法
BitBlt 用于从原设备中复制位图到目标设备,弊端,做投屏抓屏时候可能会比较慢,帧率比较低
头文件:(代码来源于网络,目前无法溯源)
#pragma once #include <windows.h> #include <string> #include<wingdi.h> 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; void SaveDCtoBmp(); 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这个对象是用来存储成对出现的参数,比如,一个矩形框的左上角坐标、宽度和高度 RECT clientRect_; POINT bitbltStartPoint_;//点坐标 int bmpDataSize_;//位图缓冲大小 };
实现:
#include "stdafx.h" #include "Bit.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 * 3;//24bit 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 = 24; bitmapInfo.bmiHeader.biSizeImage = clientRectWidth * clientRectHeight; bitmapInfo.bmiHeader.biCompression = BI_RGB; scrDc_ = ::GetWindowDC(hwnd_); //获取窗口DC(设备场景) memDc_ = ::CreateCompatibleDC(scrDc_); //缓冲内存DC //创建应用程序可以直接写入的、与设备无关的位图(DIB) bitsPtr_ = nullptr; 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; } void DibCaptureHelper::SaveDCtoBmp() { if (bitsPtr_) { BITMAPINFOHEADER bmInfoHeader = { 0 }; bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfoHeader.biWidth = clientRect_.right - clientRect_.left; bmInfoHeader.biHeight = clientRect_.bottom - clientRect_.top; bmInfoHeader.biPlanes = 1; bmInfoHeader.biBitCount = 24; //Bimap file header in order to write bmp file BITMAPFILEHEADER bmFileHeader = { 0 }; bmFileHeader.bfType = 0x4d42; //bmp int size1 = sizeof(BITMAPFILEHEADER); int size2 = sizeof(BITMAPINFOHEADER); bmFileHeader.bfOffBits = size1 + size2; bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8) FILE* fptr = fopen("./desp.bmp", "wb+"); if (fptr) { fwrite(&bmFileHeader, sizeof(BITMAPFILEHEADER),1,fptr); fwrite(&bmInfoHeader, sizeof(BITMAPINFOHEADER), 1, fptr); DWORD len = ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); fwrite(bitsPtr_, len, 1, fptr); fclose(fptr); } } }
调用:
#include "stdafx.h" #include"BIt.h" #include <windows.h> int main() { HWND winHandle = GetDesktopWindow(); auto obj = new DibCaptureHelper(); obj->Init(winHandle); obj->Capture(); obj->SaveDCtoBmp(); return 0; }
屏幕截图结果:
标签:const,Windows,hwnd,nullptr,return,_.,抓屏,DibCaptureHelper,GDI From: https://www.cnblogs.com/8335IT/p/16863057.html