c++ - 如何使用 opencv 和 Qt 对桌面的一部分进行拍照
问题描述
在此先感谢您的帮助。所以下面我正在尝试创建一个截图工具。我使用 Qt 创建了一个小部件并使其几乎透明。用户使用鼠标创建一个他们想要复制的正方形区域。我可以让它复制一个部分,而不是写入部分。我使用 getcursor 函数来获取用户光标位置a 以及正方形的终点和起点。我将我的小部件设置为我的屏幕大小,然后使用我的 void 函数拍摄整个桌面的照片(使用我的小部件窗口的大小作为我的图像大小)。然而,屏幕和图像的 x,y 值不会“重叠”,而不是获取用户绘制的正方形中的内容,而是获取屏幕上的其他正方形。有没有什么办法解决这一问题?
Frame_Record::Frame_Record(QWidget* parent) : QWidget(parent)
{
//this->setStyleSheet("background-color:rgba(0,0,0,0)");
this->setWindowState(Qt::WindowFullScreen);
this->setWindowOpacity(0.1);
this->setStyleSheet("QWidget{background:#000000}");
x_size = this->size().width();
y_size = this->size().height();
//cv::waitKey(0);
//setAttribute(Qt::WA_TranslucentBackground);
/*setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
//setAttribute(Qt::WA_PaintOnScreen);
//setAttribute(Qt::transparent);
setAttribute(Qt::WA_MouseNoMask,true);
setAttribute(Qt::WA_MouseTracking,true);*/
}
void Frame_Record::mousePressEvent(QMouseEvent* events)
{
POINT start;
GetCursorPos(&start);
qDebug() << "Mouse pressed PRessed";
x_start = start.x;
y_start = start.y;
}
void Frame_Record::mouseReleaseEvent(QMouseEvent* events)
{
qDebug() << "Mouse unpressed";
qDebug() << x_start;
qDebug() << y_start;
qDebug() << x_end;
qDebug() << y_end;
POINT end;
GetCursorPos(&end);
x_end = end.x;
y_end = end.y;
get_Image(y_size, x_size); //y then x
this->close();
}
void Frame_Record::mouseMoveEvent(QMouseEvent* events)
{
POINT end;
GetCursorPos(&end);
x_end = end.x;
y_end = end.y;
qDebug() << "mouse is moving";
}
void Frame_Record::get_Image(int screen_w, int screen_h)
{
HBITMAP bitmap;
cv::Mat pic;
HDC hdcSys = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcSys);
void* ptrBitmapPixels;
BITMAPINFO bInfo;
HDC hdc{};
ZeroMemory(&bInfo, sizeof(BITMAPINFO));
bInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bInfo.bmiHeader.biWidth = screen_w;
bInfo.bmiHeader.biHeight = -screen_h;
bInfo.bmiHeader.biPlanes = 1;
bInfo.bmiHeader.biBitCount = 32;
bitmap = CreateDIBSection(hdc, &bInfo, DIB_RGB_COLORS, &ptrBitmapPixels, NULL, 0);
SelectObject(hdcMem, bitmap);
pic =cv::Mat(screen_h, screen_w, CV_8UC4, ptrBitmapPixels, 0);
BitBlt(hdcMem, 0, 0, screen_w, screen_h, hdcSys, 0, 0, SRCCOPY);
cv::Mat mod_pic(pic, cv::Range(x_start, x_end), cv::Range(y_start, y_end));
// pic(cv::Rect(x_start, y_start, x_start - x_end, y_start - y_end));
// Mat matRef=matBitmap(Range(100,200), Range(100,200));
//bitwise_not(matRef,matRef);
cv::imshow("Title", mod_pic);
cv::waitKey(0);
cv::destroyAllWindows();
}
解决方案
您可以在 Qt 中尝试以下代码来获取屏幕
QScreen *screen = // init screen first (application.primaryScreen();)
QRect rect = screen->geometry();
// instead you can also use your x and y coordinates
QPixmap pixmap = screen->grabWindow(0, rect .x(), rect .y(), rect .width(), rect .height());
然后你可以做你想做的事QPixmap
。
推荐阅读
- javascript - JQuery:在特定页面上的输入字段上设置焦点
- amazon-web-services - AWS S3 静态网站可在 /page.html 而不是 /page 访问
- android - 在android上打开键盘时的布局问题
- angular - Angular 中可观察到的数据未定义
- json - JSON 解析问题:“预期解码数组
而是找到了一本字典。” - docker - 在运行 Dockerfile 时接受许可条款
- json - Postgres:如何返回 json 类型的投影数据
- python - Google Kickstart Round E 2020 最长算术运行时错误
- node.js - 数组长度未显示
- terraform - 将 terraform 0.12.6 切换到 0.13.0 给我 provider["registry.terraform.io/-/null"] 是必需的,但它已被删除