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;
}
相关推荐
vueTmp2 天前
VSCode 插件离线下载攻略
visual studio code
穷人小水滴6 天前
在 Android 设备上写代码 (Termux, code-server)
android·linux·visual studio code
哎呦你好10 天前
VS Code 安装后设置中文界面并添加常用插件的详细指南
编辑器·visual studio code
魔术师ID19 天前
vue2.0 组件生命周期
前端·javascript·vue.js·学习·visual studio code
MingT 明天你好!19 天前
在vs code 中无法运行npm并报无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查
前端·npm·node.js·visual studio code
Ynov23 天前
详细解释api
javascript·visual studio code
程序员Bears1 个月前
现代前端工具链深度解析:从包管理到构建工具的完整指南
前端·python·visual studio code
formulahendry1 个月前
把 MCP Server 打包进 VS Code extension
visual studio code·vs code·mcp
程序员Bears1 个月前
深入理解CSS3:Flex/Grid布局、动画与媒体查询实战指南
前端·css3·媒体·visual studio code
优弧1 个月前
VSCode配置重置完全指南
visual studio code