EVE111

Beep.h

cpp 复制代码
#pragma once
#include <cstdio>
#include <windows.h>
#define qdo 262 
#define qre 294
#define qmi 330     //q前缀为低音,1后缀为高音,s前缀为半音阶 
#define qfa 349
#define qso 392
#define qla 440
#define qsi 494
#define do 523
#define re 578
#define mi 659
#define fa 698
#define so 784
#define la 880
#define si 988
#define do1 1046
#define re1 1175
#define mi1 1318
#define fa1 1480
#define so1 1568
#define la1 1760
#define si1 1976
#define sqdo 277
#define sqre 311
#define sqfa 370
#define sqso 415
#define sqla 466
#define sdo 554
#define sre 622
#define sfa 740
#define sso 831
#define sla 932
#define sdo1 1046
#define sre1 1245
#define sfa1 1480
#define sso1 1661
#define sla1 1865


#define pai  400
#define ban  200
#define ting  128

Screenshot.h

cpp 复制代码
#pragma once
#include <Windows.h>
#include <opencv2/opencv.hpp>

class Screenshot
{
public:
    Screenshot();
    double static getZoom();
    cv::Mat getScreenshot();
    cv::Mat getScreenshot(int x, int y, int width, int height);

private:
    int m_width;
    int m_height;
    HDC m_screenDC;
    HDC m_compatibleDC;
    HBITMAP m_hBitmap;
    LPVOID m_screenshotData = nullptr;
};

Sreenshot.cpp

cpp 复制代码
#include "Screenshot.h"
using cv::Mat;

Screenshot::Screenshot()
{
    double zoom = getZoom();
    m_width = GetSystemMetrics(SM_CXSCREEN) * zoom;
    m_height = GetSystemMetrics(SM_CYSCREEN) * zoom;
    m_screenshotData = new char[m_width * m_height * 4];
    memset(m_screenshotData, 0, m_width);

    // 获取屏幕 DC
    m_screenDC = GetDC(NULL);
    m_compatibleDC = CreateCompatibleDC(m_screenDC);

    // 创建位图
    m_hBitmap = CreateCompatibleBitmap(m_screenDC, m_width, m_height);
    SelectObject(m_compatibleDC, m_hBitmap);
}

/* 获取整个屏幕的截图 */
Mat Screenshot::getScreenshot()
{
    // 得到位图的数据
    BitBlt(m_compatibleDC, 0, 0, m_width, m_height, m_screenDC, 0, 0, SRCCOPY);
    GetBitmapBits(m_hBitmap, m_width * m_height * 4, m_screenshotData);

    // 创建图像
    Mat screenshot(m_height, m_width, CV_8UC4, m_screenshotData);

    return screenshot;
}

/** @brief 获取指定范围的屏幕截图
 * @param x 图像左上角的 X 坐标
 * @param y 图像左上角的 Y 坐标
 * @param width 图像宽度
 * @param height 图像高度
 */
Mat Screenshot::getScreenshot(int x, int y, int width, int height)
{
    Mat screenshot = getScreenshot();
    return screenshot(cv::Rect(x, y, width, height));
}

/* 获取屏幕缩放值 */
double Screenshot::getZoom()
{
    // 获取窗口当前显示的监视器
    HWND hWnd = GetDesktopWindow();
    HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);

    // 获取监视器逻辑宽度
    MONITORINFOEX monitorInfo;
    monitorInfo.cbSize = sizeof(monitorInfo);
    GetMonitorInfo(hMonitor, &monitorInfo);
    int cxLogical = (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left);

    // 获取监视器物理宽度
    DEVMODE dm;
    dm.dmSize = sizeof(dm);
    dm.dmDriverExtra = 0;
    EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &dm);
    int cxPhysical = dm.dmPelsWidth;

    return cxPhysical * 1.0 / cxLogical;
}

main.cpp

cpp 复制代码
#include "Screenshot.h"
#include "Beep.h"
#include<Windows.h>
using namespace std;
using namespace cv;


// 发出警报
void warning()
{
    while (true)
    {
        Beep(la, pai);
    }
}

// 显示截取的图像
void show(Mat img_wite,Mat img_red)
{

    imshow("src", img_wite);
    waitKey();
    system("pause");

    imshow("src", img_red);
    waitKey();
    system("pause");
}

// 图像锐化
void alter(Mat img_wite)
{

    for (int j = 0; j < img_wite.rows; j++)
    {
        for (int i = 0; i < img_wite.cols; i++)
        {

            //printf("%d %d %d \n", img_wite.at<cv::Vec3b>(j, i)[0], img_wite.at<cv::Vec3b>(j, i)[1], img_wite.at<cv::Vec3b>(j, i)[2]);


            // 如果rgb值中其中一个值大于255,则将其值重新赋值为其他俩值的平均数,因为本图像只有灰度
            if (img_wite.at<cv::Vec3b>(j, i)[0] == 255)
            {
                img_wite.at<cv::Vec3b>(j, i)[0] = (img_wite.at<cv::Vec3b>(j, i)[1] + img_wite.at<cv::Vec3b>(j, i)[2]) / 2;
            }
            if (img_wite.at<cv::Vec3b>(j, i)[1] == 255)
            {
                img_wite.at<cv::Vec3b>(j, i)[1] = (img_wite.at<cv::Vec3b>(j, i)[0] + img_wite.at<cv::Vec3b>(j, i)[2]) / 2;
            }
            if (img_wite.at<cv::Vec3b>(j, i)[2] == 255)
            {
                img_wite.at<cv::Vec3b>(j, i)[2] = (img_wite.at<cv::Vec3b>(j, i)[1] + img_wite.at<cv::Vec3b>(j, i)[0]) / 2;
            }



            // 然后来判断他是深色背景还是浅色字体

            if (img_wite.at<cv::Vec3b>(j, i)[0] +
                img_wite.at<cv::Vec3b>(j, i)[1] + img_wite.at<cv::Vec3b>(j, i)[2] > 250
                )
            {
                img_wite.at<cv::Vec3b>(j, i)[0] = 255;
                img_wite.at<cv::Vec3b>(j, i)[1] = 255;
                img_wite.at<cv::Vec3b>(j, i)[2] = 255;
            }
            else
            {
                img_wite.at<cv::Vec3b>(j, i)[0] = 0;
                img_wite.at<cv::Vec3b>(j, i)[1] = 0;
                img_wite.at<cv::Vec3b>(j, i)[2] = 0;
            }
            //printf("%d", img_wite.at<cv::Vec3b>(j, i)[2] == 255 ? 1 : 0);
        }
        //printf("\n");
    }
}


// 俩Mat进行比较,判断是否相同
bool comp(Mat mat1, Mat mat2)
{

    int diff = 0;
    for (int j = 0; j < mat1.rows; j++)
    {
        for (int i = 0; i < mat1.cols; i++)
        {
            if (!((int)mat1.at<cv::Vec3b>(j, i)[0] == (int)mat2.at<cv::Vec3b>(j, i)[0] &&
                (int)mat1.at<cv::Vec3b>(j, i)[1] == (int)mat2.at<cv::Vec3b>(j, i)[1] &&
                (int)mat1.at<cv::Vec3b>(j, i)[2] == (int)mat2.at<cv::Vec3b>(j, i)[2]))
            {
                diff++;
              /*  cout << (int)mat1.at<cv::Vec3b>(j, i)[0] << (int)mat2.at<cv::Vec3b>(j, i)[0] << endl;
                cout << (int)mat1.at<cv::Vec3b>(j, i)[1] << (int)mat2.at<cv::Vec3b>(j, i)[1] << endl;
                cout << (int)mat1.at<cv::Vec3b>(j, i)[2] << (int)mat2.at<cv::Vec3b>(j, i)[2] << endl;*/
                //return false;
            }
        }
    }
    if (diff>100)
    {
        return false;
    }
    else
    {
        return true;
    }
}


int main()
{
    system("pause");
    Screenshot screenshot1;
    Screenshot screenshot;
    // 截取全屏
    //Mat img = screenshot.getScreenshot();

    // 截取红白都没有的状态
    Mat src_wite;
    Mat src_red;
    src_wite = screenshot1.getScreenshot(194, 740, 30, 40);
    src_red = screenshot1.getScreenshot(338, 740, 30, 40);
    alter(src_red);
    alter(src_wite);

    Mat img_wite;
    Mat img_red;
    while (true)
    {
        Sleep(1000);
        img_wite = screenshot.getScreenshot(194, 740, 30, 40);
        img_red = screenshot.getScreenshot(338, 740, 30, 40);
        // 图像锐化
        alter(img_red);
        alter(img_wite);

        // 如果俩都没发生变化,返回的都是true
        if (comp(img_red, src_red)==false || comp(img_wite, src_wite)==false)
        {
            cout << "开始警报" << endl;
            warning();
        }
        else
        {
            cout << "安全" << endl;
        }
    }




    // 临时显示截取的图片
    //show(img_wite, img_red);

    // 释放内存
    img_wite.release();
    img_red.release();


    src_wite.release();
    src_red.release();

    // 将mat保存
    // imwrite("screenshot_part.jpg", img_);
    return 0;
}
相关推荐
Yang.991 天前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
WXDWIN.3 天前
C++语言之模版与类型转换
c语言·开发语言·c++·visualstudio·visual studio code
卷卷的小趴菜学编程3 天前
时间类的实现
c语言·开发语言·数据结构·c++·算法·visual studio code
Eric_见嘉8 天前
真的能无限试(白)用(嫖)cursor 吗?
前端·visual studio code
heilai410 天前
workerman的安装与使用
c++·websocket·http·php·phpstorm·visual studio code
移民找老国16 天前
加拿大移民新风向
java-ee·maven·phpstorm·visual studio code·nio
闪亮Girl18 天前
vs2015安装插件QtPackage.vsix等vsix文件类型
visual studio code
SuperYing20 天前
💯What?维护新老项目频繁切换node版本太恼火?开发一个vscode插件自动切换版本,从此告别烦恼
前端·visual studio code
羊小猪~~20 天前
数据结构C语言描述1(图文结合)--顺序表讲解,实现,表达式求值应用,考研可看
java·c语言·数据结构·c++·链表·visual studio code·visual studio
羊小猪~~20 天前
C/C++语言基础--C++模板与元编程系列三(变量模板、constexpr、萃取等…………)
java·c语言·开发语言·c++·visual studio code·visual studio