编写qml客户端程序常需要获取颜色和图标,可用win32 api获取

在使用qml照搬某些界面时,需要选取某些svg图标或者颜色,使用ps有时会因为界面问题带来不方便,因而可以使用qt qml 和win32 api编写建议的辅助类。

Project.pro里添加opencv和win32 api相应配置

...
QT += svg 

...
# opencv  opencv配置
win32:CONFIG(release, debug|release): LIBS += -LD:/opencv/build/x64/vc15/lib/ -lopencv_world410
else:win32:CONFIG(debug, debug|release): LIBS += -LD:/opencv/build/x64/vc15/lib/ -lopencv_world410d
else:unix: LIBS += -LD:/opencv/build/x64/vc15/lib/ -lopencv_world410
INCLUDEPATH += D:/opencv/build/include
INCLUDEPATH += D:/opencv/build/include/opencv2
DEPENDPATH += D:/opencv/build/include

unix: CONFIG += link_pkgconfig
unix: PKGCONFIG += /usr/local/lib/pkgconfig/opencv4.pc


win32:LIBS += -lUser32 -lgdi32

在win32helper.h里添加
#ifndef WIN32HELPER_H
#define WIN32HELPER_H

#include <QColor>
#include <QImage>
#include <QObject>
#include <QPainter>
#include <QPointF>
#include <QSvgRenderer>

namespace ld {

class Win32Helper : public QObject
{
    Q_OBJECT
public:
    explicit Win32Helper(QObject *parent = nullptr);

    Q_INVOKABLE QPoint getCursorPosition(); // 获取光标位置
    Q_INVOKABLE QColor getPixelColor(int x, int y); // 获取坐标(x,y)的颜色
    Q_INVOKABLE void captureSvg(const QString &filePath = "output.svg", QSize size = QSize(32,32)); // 截取当前光标为中心的size为尺寸的svg图标 存为filePath文件

signals:

};

}
#endif // WIN32HELPER_H

win32helper.cpp里添加实现

#include "win32helper.h"
#include <QSvgGenerator>
#include <windows.h>
#include <opencv.hpp>
#include "ImageUtil.h"

using namespace ld;
Win32Helper::Win32Helper(QObject *parent) : QObject(parent)
{

}

QPoint ld::Win32Helper::getCursorPosition()
{
    POINT point;
    GetCursorPos(&point);
    return QPoint(point.x, point.y);
}

QColor ld::Win32Helper::getPixelColor(int x, int y)
{
    HDC hdc = GetDC(NULL);
    COLORREF color = GetPixel(hdc, x, y);
    ReleaseDC(NULL, hdc);
    return QColor(GetRValue(color), GetGValue(color), GetBValue(color));
}

void Win32Helper::captureSvg(const QString &filePath, QSize size)
{
    int width = size.width();
    int height = size.height();
    HDC hdcWindow = GetDC(NULL);
    HDC hdcMemDC = CreateCompatibleDC(hdcWindow);

    HBITMAP hBitmap = CreateCompatibleBitmap(hdcWindow, width, height);
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMemDC, hBitmap);
    POINT point;
    GetCursorPos(&point);
    int x = point.x;
    int y = point.y;

    BitBlt(hdcMemDC, 0, 0, width, height, hdcWindow, x - width/2, y - height/2, SRCCOPY);

    QImage image = QImage(width, height, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    BITMAPINFOHEADER bi;
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = width;
    bi.biHeight = -height; // top-down
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    GetDIBits(hdcMemDC, hBitmap, 0, height, image.bits(), (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    SelectObject(hdcMemDC, hOldBitmap);
    DeleteObject(hBitmap);
    DeleteDC(hdcMemDC);
//    ReleaseDC(hwnd, hdcWindow);
    // Convert QImage to QPixmap
//    QPixmap pixmap = QPixmap::fromImage(image);
    QPixmap pixmap;
    image.convertToFormat(QImage::Format_Grayscale8);
//    QImage mirroredImage = image.mirrored(false, true); // 水平翻转
//    cv::Mat mat = imageToMat(image);
//    cv::Canny(mat, mat, 10,20); // 需要注意cv::Canny处理的是灰度图像
//    pixmap = QPixmap::fromImage(matToImage(mat));
    pixmap = QPixmap::fromImage(image);


    // Convert QPixmap to SVG
    QSvgGenerator svgGenerator;
    svgGenerator.setFileName(filePath);
    svgGenerator.setSize(pixmap.size());
    svgGenerator.setViewBox(pixmap.rect());
    svgGenerator.setTitle("Window Capture");
    svgGenerator.setDescription("Captured image from window at mouse position");

    QPainter painter;
    painter.begin(&svgGenerator);
    painter.drawPixmap(0, 0, pixmap);
    painter.end();
}

这里保存的是灰度svg, 有时由于图片格式等问题需要注意使用水平翻转获取真实图片。

在qml里使用透明的窗体和键盘事件来获取当前光标位置和颜色,以及截取附近的图标。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值