电脑截屏的方法(qt 数据库编程)

最近一个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。一次截屏操作就相当于相机拍一张照片。这样的好处是我这里有大量的相机图像处理的代码模块。将截屏封装成相机之后,就可以非常便捷的连接我的既有代码了。这种方法在设计模式中成为“适配器模式”。

下面是代码:

 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();

本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(0)
上一篇 2023年3月9日 下午2:28
下一篇 2023年3月9日 下午3:48

相关推荐