Qt 截屏的方法

  • Post author:
  • Post category:其他


最近一个Qt(C++)的项目需要用到截屏的功能,就花时间研究了一下如何实现。

Qt 确实是好用,截屏只需要下面三行代码就够了。

1 QDesktopWidget *desk = QApplication::desktop();
2 QScreen * screen = QGuiApplication::primaryScreen();
3 QPixmap p = screen->grabWindow(desk->winId());

这三行代码第一行是获取桌面的窗体对象。

第二行是获得一个 QScreen 对象。

第三行是截取屏幕上窗体对象所在区域的图像。

截取的结果是个QPixmap ,如果需要进一步处理的话,可以转化为 QIamge,一行代码就可以了。

QImage image = p.toImage();

原理就这么简单,但是我将这个代码封装了一下,将截屏功能封装成了一个 Camera。一次截屏操作就相当于相机拍一张照片。这样的好处是我这里有大量的相机图像处理的代码模块。将截屏封装成相机之后,就可以非常便捷的连接我的既有代码了。这种方法在设计模式中成为“适配器模式”。

下面是代码:




本文福利,








费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击





费领取↓↓



  1 #ifndef SCREENCAMERA_H
  2 #define SCREENCAMERA_H
  3 
  4 #include <QThread>
  5 #include <QObject>
  6 #include <QScreen>
  7 #include <QTimer>
  8 
  9 class ScreenCamera;
 10 
 11 /**
 12  * @brief The ScreenCameraInfo class 查询屏幕相机的信息的类
 13  * 用这个类可以查到当前计算机接了几个显示器,给出每个显示器的名称(deviceName)
 14  */
 15 class ScreenCameraInfo
 16 {
 17     friend class ScreenCamera;
 18 public:
 19     explicit ScreenCameraInfo(QScreen * screen = nullptr);
 20     ScreenCameraInfo(const ScreenCameraInfo &info);
 21     /**
 22      * @brief description 没有实现,返回空字符串
 23      * @return 返回空字符串。
 24      */
 25     QString description() const;
 26     /**
 27      * @brief deviceName 给出屏幕的名称,比如 "\\\\.\\DISPLAY1", "VGA1" 一类的名称。
 28      * @return
 29      */
 30     QString deviceName() const;
 31     bool isNull() const;
 32     bool operator!=(const ScreenCameraInfo &other) const;
 33     ScreenCameraInfo &operator=(const ScreenCameraInfo &other);
 34     bool operator==(const ScreenCameraInfo &other) const;
 35 
 36     static QList<ScreenCameraInfo> availableCameras();
 37     static ScreenCameraInfo defaultCamera();
 38 
 39 private:
 40     QScreen* m_screen;
 41 };
 42 
 43 /**
 44  * @brief The ScreenCamera class 将截屏功能封装成一个相机,可以像相机一样的操作。
 45  */
 46 class ScreenCamera : public QThread
 47 {
 48     Q_OBJECT
 49 public:
 50     explicit ScreenCamera(QObject *parent = 0);
 51     explicit ScreenCamera(ScreenCameraInfo &info, QObject *parent = 0);
 52     /**
 53      * @brief openDevice 打开一个特定的截屏相机,当计算机连接了多个显示器时通过这个 info 指定截取某一个屏幕的图像
 54      * @param info
 55      * @return
 56      */
 57     bool openDevice(const ScreenCameraInfo &info);
 58     /**
 59      * @brief setFrameRate 设置定时截屏的帧率。这里模仿相机的帧率设置。
 60      * @param fps  frame per second 每秒的截屏数量。 [0.001 - 50]
 61      */
 62     void setFrameRate(double fps);
 63     /**
 64      * @brief setRoi 设置感兴趣的区域,利用这个函数我们可以只截取屏幕的一部分区域
 65      * @param x 截屏区域的起始X坐标
 66      * @param y 截屏区域的起始Y坐标
 67      * @param width 截屏区域的宽度,-1 表示完整的屏幕宽度
 68      * @param height 截屏区域的高度,-1 表示完整的屏幕高度
 69      */
 70     void setRoi(int x, int y, int width, int height);
 71     void run() override;
 72     /**
 73      * @brief capture 获取截屏图像
 74      * @return
 75      */
 76     QImage capture();
 77 signals:
 78     /**
 79      * @brief imageChanged 定时截取图像时没截取一帧图像就激发一次这个信号
 80      * @param image
 81      */
 82     void imageChanged(const  QImage& image);
 83 public slots:
 84     /**
 85      * @brief start 开始图像采集
 86      */
 87     void start();
 88     /**
 89      * @brief stop 停止图像采集
 90      */
 91     void stop();
 92 
 93 private:
 94     int m_sleepInterval;
 95     QScreen* m_screen;
 96     int m_x;
 97     int m_y;
 98     int m_width;
 99     int m_height;
100 };
101 
102 #endif // SCREENCAMERA_H
  1 #include "ScreenCamera.h"
  2 #include <QApplication>
  3 #include <QDesktopWidget>
  4 #include <QDebug>
  5 
  6 ScreenCameraInfo::ScreenCameraInfo(const ScreenCameraInfo &info)
  7     :m_screen(nullptr)
  8 {
  9     m_screen = info.m_screen;
 10 }
 11 
 12 ScreenCameraInfo::ScreenCameraInfo(QScreen * screen)
 13     :m_screen(nullptr)
 14 {
 15     m_screen = screen;
 16 }
 17 
 18 bool ScreenCameraInfo::isNull() const
 19 {
 20     return (m_screen == nullptr);
 21 }
 22 
 23 QString ScreenCameraInfo::description() const
 24 {
 25     return "";
 26 }
 27 QString ScreenCameraInfo::deviceName() const
 28 {
 29     if(m_screen == nullptr) return "";
 30     return m_screen->name();
 31 }
 32 
 33 ScreenCameraInfo ScreenCameraInfo::defaultCamera()
 34 {
 35     QScreen * w = QGuiApplication::primaryScreen();
 36     return ScreenCameraInfo(w);
 37 }
 38 
 39 QList<ScreenCameraInfo> ScreenCameraInfo::availableCameras()
 40 {
 41     QList<QScreen *> list = QGuiApplication::screens();
 42     QList<ScreenCameraInfo> info;
 43     foreach (QScreen * s, list)
 44     {
 45         ScreenCameraInfo i(s);
 46         info.append(i);
 47     }
 48 
 49     return info;
 50 }
 51 
 52 bool ScreenCameraInfo::operator!=(const ScreenCameraInfo &other) const
 53 {
 54     return (m_screen != other.m_screen);
 55 }
 56 
 57 ScreenCameraInfo & ScreenCameraInfo::operator=(const ScreenCameraInfo &other)
 58 {
 59     m_screen = other.m_screen;
 60     return *this;
 61 }
 62 
 63 bool ScreenCameraInfo::operator==(const ScreenCameraInfo &other) const
 64 {
 65     return m_screen == other.m_screen;
 66 }
 67 
 68 
 69 ScreenCamera::ScreenCamera(ScreenCameraInfo &info, QObject *parent) : QThread(parent)
 70 {
 71     m_screen = info.m_screen;
 72     m_sleepInterval = 500;
 73     m_x = 0;
 74     m_y = 0;
 75     m_width = -1;
 76     m_height = -1;
 77 }
 78 
 79 ScreenCamera::ScreenCamera(QObject *parent) : QThread(parent)
 80 {
 81     m_screen = nullptr;
 82     m_sleepInterval = 500;
 83     m_x = 0;
 84     m_y = 0;
 85     m_width = -1;
 86     m_height = -1;
 87 }
 88 
 89 bool ScreenCamera::openDevice(const ScreenCameraInfo &info)
 90 {
 91     m_screen = info.m_screen;
 92     return (m_screen);
 93 }
 94 
 95 void ScreenCamera::setFrameRate(double fps)
 96 {
 97     fps = qBound(0.001, fps, 50.0);
 98     m_sleepInterval = 1000 / fps;  
 99 }
100 
101 void ScreenCamera::setRoi(int x, int y, int width, int height)
102 {
103     if(m_screen)
104     {
105         QRect rect = m_screen->geometry();
106 
107         m_x = qBound(0, x, rect.width());
108         m_y = qBound(0, y, rect.height());
109         m_width = qBound(-1, width, rect.width());
110         m_height = qBound(-1, height, rect.height());
111     }
112 }
113 
114 void ScreenCamera::run()
115 {
116     while(1)
117     {
118         if(m_screen)
119         {
120             QDesktopWidget *desk = QApplication::desktop();
121             //qDebug() << "m_width = " << m_width;
122             //qDebug() << "m_height = " << m_height;
123             QPixmap p = m_screen->grabWindow(desk->winId(), m_x, m_y, m_width, m_height);
124             QImage image = p.toImage();
125             emit imageChanged(image);
126         }
127         msleep(m_sleepInterval);
128     }
129 }
130 
131 QImage ScreenCamera::capture()
132 {
133     if(m_screen)
134     {
135         QDesktopWidget *desk = QApplication::desktop();
136         QPixmap p = m_screen->grabWindow(desk->winId(), m_x, m_y, m_width, m_height);
137         QImage image = p.toImage();
138         return image;
139     }
140     return QImage();
141 }
142 
143 void ScreenCamera::stop()
144 {
145     terminate();
146 }
147 
148 void ScreenCamera::start()
149 {
150     QThread::start(QThread::InheritPriority);
151 }

用法很简答,下面给个代码片段:

1 ScreenCameraInfo info = ScreenCameraInfo::defaultCamera();
2 qDebug() << info.deviceName();
3 m_screenCamera = new ScreenCamera(info);
4 connect(m_screenCamera, SIGNAL(imageChanged(QImage)), m_cameraImage, SLOT(setImage(QImage)));
5 m_screenCamera->setRoi(0, 0, 500, 500);
6 m_screenCamera->start();




本文福利,








费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击





费领取↓↓





版权声明:本文为m0_73443478原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。