c/c++语言开发共享C++抓图服务

基于前两篇抓图文章,本文将抓图提取为一个服务,实现不同场景下抓图需求的封装。 C++使用BitBlt进行窗口抓图 C++使用PrintWindow进行窗口抓图 首先是抓图服务: ICaptureHelper.h #pragma once #include <windows.h> #include < …

基于前两篇抓图文章,c/c++开发分享C++抓图务将抓图提取为一个服务,实现不同场景下抓图需求的封装。

c++使用bitblt进行窗口抓图

c++使用printwindow进行窗口抓图

首先是抓图服务:

icapturehelper.h 

#pragma once  #include <windows.h> #include <string> using std::string;  class icapturehelper { public:     virtual ~icapturehelper() {}     virtual bool init(const string& windowname) = 0;     virtual bool init(hwnd hwnd) = 0;     virtual void cleanup() = 0;     virtual bool refreshwindow() = 0;     virtual bool changewindowhandle(const string& windowname) = 0;     virtual bool changewindowhandle(hwnd hwnd) = 0;     virtual bool capture() = 0;      virtual const rect& getwindowrect() const = 0;     virtual const rect& getclientrect() const = 0;     virtual int getbitmapdatasize() const = 0;     virtual hbitmap getbitmap() const = 0;     virtual void* getbitmapaddress() const = 0; };

captureservice.h

#pragma once  #include "icapturehelper.h" #include <map> using std::map;  class captureservice { public:     captureservice() = default;     static captureservice& getinstance();      enum capturetype     {         //使用createdibsection抓图,速度快,但是无法抓取d3d等渲染的窗口         createdibsection = 0,          //使用printwindow抓图,速度慢(16ms左右),但是可以抓取d3d等渲染的窗口         printwindow     };      bool registercapture(string name, string windowname, capturetype type = createdibsection); //注册抓图服务     bool registercapture(string name, hwnd hwnd, capturetype type = createdibsection); //注册抓图服务     void unregistercapture(string name); //注销抓图服务     bool isregister(string name); //获取是否已注册抓图服务      bool refreshwindow(string name); //刷新窗口     bool changewindowhandle(string name, string windowname); //修改窗口句柄     bool changewindowhandle(string name, hwnd hwnd); //修改窗口句柄     bool capture(string name); //抓图      bool getwindowrect(string name, rect& winrect); //获取窗口尺寸     bool getclientrect(string name, rect& clientrect); //获取窗口客户区尺寸     bool getbitmapdatasize(string name, int& bmpdatasize); //获取抓图数据大小     bool getbitmap(string name, hbitmap& bitmap); //获取窗口位图     bool getbitmapaddress(string name, void** bitsptr); //获取窗口位图地址      void cleanup(); //清理所有抓图服务  private:     ~captureservice();  private:     map<string, icapturehelper*> capturehelpers_; };

captureservice.cpp

#include "stdafx.h" #include "captureservice.h" #include "dibcapturehelper.h" #include "printcapturehelper.h"   captureservice::~captureservice() {     cleanup(); }  captureservice& captureservice::getinstance() {     static captureservice instance;     return instance; }  bool captureservice::registercapture(string name, string windowname, capturetype type /* = createdibsection */) {     const auto hwnd = ::findwindowa(nullptr, windowname.c_str());     return registercapture(name, hwnd, type); }  bool captureservice::registercapture(string name, hwnd hwnd, capturetype type /* = createdibsection */) {     if (name.empty() || capturehelpers_.find(name) != capturehelpers_.end())     {         return false;     }      icapturehelper* helper;     switch (type)     {     case createdibsection:         helper = new dibcapturehelper();         break;     case printwindow:         helper = new printcapturehelper();         break;     default:         return false;     }      if (helper == nullptr)     {         return false;     }      if (!helper->init(hwnd))     {         delete helper;         return false;     }      capturehelpers_[name] = helper;     return true; }  void captureservice::unregistercapture(string name) {     if (name.empty() || capturehelpers_.find(name) == capturehelpers_.end())     {         return;     }      auto* capturehelper = capturehelpers_[name];     if (capturehelper != nullptr)     {         capturehelper->cleanup();         delete capturehelper;     }      capturehelpers_.erase(name); }  bool captureservice::isregister(string name) {     return !name.empty() && capturehelpers_.find(name) != capturehelpers_.end(); }  bool captureservice::refreshwindow(string name) {     if (!isregister(name))     {         return false;     }     return capturehelpers_[name]->refreshwindow(); }  bool captureservice::changewindowhandle(string name, string windowname) {     if (!isregister(name))     {         return false;     }     return capturehelpers_[name]->changewindowhandle(windowname); }  bool captureservice::changewindowhandle(string name, hwnd hwnd) {     if (!isregister(name))     {         return false;     }     return capturehelpers_[name]->changewindowhandle(hwnd); }  bool captureservice::capture(string name) {     if (!isregister(name))     {         return false;     }     return capturehelpers_[name]->capture(); }  bool captureservice::getwindowrect(string name, rect& winrect) {     if (!isregister(name))     {         return false;     }     winrect = capturehelpers_[name]->getwindowrect();     return true; }  bool captureservice::getclientrect(string name, rect& clientrect) {     if (!isregister(name))     {         return false;     }     clientrect = capturehelpers_[name]->getclientrect();     return true; }  bool captureservice::getbitmapdatasize(string name, int& bmpdatasize) {     if (!isregister(name))     {         return false;     }     bmpdatasize = capturehelpers_[name]->getbitmapdatasize();     return true; }  bool captureservice::getbitmap(string name, hbitmap& bitmap) {     if (!isregister(name))     {         return false;     }     bitmap = capturehelpers_[name]->getbitmap();     return true; }  bool captureservice::getbitmapaddress(string name, void** bitsptr) {     if (!isregister(name))     {         return false;     }     *bitsptr = capturehelpers_[name]->getbitmapaddress();     return true; }  void captureservice::cleanup() {     for (auto iter = capturehelpers_.cbegin(); iter != capturehelpers_.cend(); ++iter)     {         auto* capturehelper = iter->second;         if (capturehelper != nullptr)         {             capturehelper->cleanup();             delete capturehelper;         }     }     capturehelpers_.clear(); }

其次是抓图代码封装:

abscapturehelper.h

#pragma once  #include "icapturehelper.h"  class abscapturehelper : public icapturehelper { public:     abscapturehelper();     virtual ~abscapturehelper();      bool init(const string& windowname) override;     bool init(hwnd hwnd) override;     void cleanup() override;     bool refreshwindow() override;     bool changewindowhandle(const string& windowname) override;     bool changewindowhandle(hwnd hwnd) override;     bool capture() override;      const rect& getwindowrect() const override { return windowrect_; }     const rect& getclientrect() const override { return clientrect_; }     int getbitmapdatasize() const override { return bmpdatasize_; }     hbitmap getbitmap() const override { return bitmap_; }     void* getbitmapaddress() const override { return bitsptr_; }  protected:     virtual bool initdc(const bitmapinfo& bitmapinfo) = 0;     virtual bool docapture() = 0;  protected:     hwnd hwnd_;     hdc scrdc_;     hdc memdc_;     hbitmap bitmap_;     hbitmap oldbitmap_;     void* bitsptr_;      rect windowrect_;     rect clientrect_;     int bmpdatasize_; };

abscapturehelper.cpp

#include "stdafx.h" #include "abscapturehelper.h"   abscapturehelper::abscapturehelper()     : hwnd_(nullptr)     , scrdc_(nullptr)     , memdc_(nullptr)     , bitmap_(nullptr)     , oldbitmap_(nullptr)     , bitsptr_(nullptr)     , windowrect_{ 0, 0, 0, 0 }     , clientrect_{ 0, 0, 0, 0 }     , bmpdatasize_(0) { }  abscapturehelper::~abscapturehelper() {     abscapturehelper::cleanup(); }  bool abscapturehelper::init(const string& windowname) {     const auto handle = ::findwindowa(nullptr, windowname.c_str());     if (handle == nullptr)     {         return false;     }      return init(handle); }  bool abscapturehelper::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;      //位图信息     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;      return initdc(bitmapinfo); }  void abscapturehelper::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 abscapturehelper::refreshwindow() {     const auto hwnd = hwnd_;     cleanup();     return init(hwnd); }  bool abscapturehelper::changewindowhandle(const string& windowname) {     cleanup();     return init(windowname); }  bool abscapturehelper::changewindowhandle(hwnd hwnd) {     cleanup();     return init(hwnd); }  bool abscapturehelper::capture() {     if (bitmap_ == nullptr || memdc_ == nullptr || scrdc_ == nullptr)     {         return false;     }      return docapture(); }

dibcapturehelper.h

#pragma once  #include "abscapturehelper.h"  class dibcapturehelper : public abscapturehelper { public:     dibcapturehelper();     virtual ~dibcapturehelper();  protected:     bool initdc(const bitmapinfo& bitmapinfo) override;     bool docapture() override;  private:     bool savebitmap_;     int mockpagenumber;     int bmpcount_; };

dibcapturehelper.cpp

#include "stdafx.h" #include "dibcapturehelper.h" #include <sstream>  static int bmpcount = 0; static int bmpmaxcount = 50;  dibcapturehelper::dibcapturehelper()     : savebitmap_(false)     , mockpagenumber(++bmpcount)     , bmpcount_(0) { }  dibcapturehelper::~dibcapturehelper() { }  bool dibcapturehelper::initdc(const bitmapinfo& bitmapinfo) {     scrdc_ = ::getwindowdc(hwnd_);     memdc_ = ::createcompatibledc(scrdc_);      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; }  bool dibcapturehelper::docapture() {     const auto clientrectwidth = clientrect_.right - clientrect_.left;     const auto clientrectheight = clientrect_.bottom - clientrect_.top;      const auto ret = ::bitblt(         memdc_, 0, 0, clientrectwidth, clientrectheight,         scrdc_, 0, 0, srccopy);      return ret != 0; }

printcapturehelper.h

#pragma once  #include "abscapturehelper.h"  class printcapturehelper : public abscapturehelper { public:     printcapturehelper();     virtual ~printcapturehelper();  protected:     bool initdc(const bitmapinfo& bitmapinfo) override;     bool docapture() override; };

printcapturehelper.cpp

#include "stdafx.h" #include "printcapturehelper.h"   printcapturehelper::printcapturehelper() { }  printcapturehelper::~printcapturehelper() { }  bool printcapturehelper::initdc(const bitmapinfo& bitmapinfo) {     scrdc_ = ::getwindowdc(hwnd_);     memdc_ = ::createcompatibledc(scrdc_);      bitmap_ = ::createdibsection(scrdc_, &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; }  bool printcapturehelper::docapture() {     const auto ret = ::printwindow(hwnd_, memdc_, pw_clientonly | pw_renderfullcontent);     return ret != 0; }

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ctvol.com/c-cdevelopment/599939.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐