V20260122-2.3.9

调整图片阅览的缩放逻辑。
调整柱状图文本倾斜角度。
部分小改动。
This commit is contained in:
2026-01-22 14:05:08 +08:00
parent d9fe3be143
commit 77d4315d3f
5 changed files with 42 additions and 103 deletions
+9 -8
View File
@@ -11,7 +11,7 @@
#include <QDir>
#pragma execution_character_set("utf-8")
const std::string softwareVersion = "20260112-2.3.8";
const std::string softwareVersion = "20260122-2.3.9";
const std::string euiJsonVersion = "1.0.6";
#define GigaByte 1073741824
#define globalDatabasePth "./sqlDatabase/eui_db.db" //全局数据库路径
@@ -22,6 +22,8 @@ const std::string euiJsonVersion = "1.0.6";
#define imgSaveTreadMaxCount 4 //最大存图线程数
#define jsonRpcEnable false //是否启用JSON RPC服务器
#define minimumWindowSize 1280, 720//最小窗口大小
#define histogramLabelTiltAngle 30 //柱状图标签倾斜角度
#define windowMoveFreshRate 60//窗口移动每秒的刷新率
#define sColor_Blue "51, 56, 69"
#define sColor_BlueWithWhite "64, 68, 81"
#define sColor_BlueWithBlack "46, 50, 52"
@@ -39,8 +41,7 @@ const std::string euiJsonVersion = "1.0.6";
#define sColor_Black "22, 22, 22"
#define sColor_BlackWithWhite "45, 45, 45"
//窗口设置
#define windowMoveFreshRate 60//窗口移动每秒的刷新率
struct viewerStruct {
std::string name;
@@ -61,7 +62,7 @@ struct historyPack
std::shared_ptr<std::string>filePath;
std::vector<std::string>text;
};
static QImage cvMatToQImage(cv::Mat& src)
static QImage cvMatToQImage(const cv::Mat& src)
{
if (src.channels() == 1) { // if grayscale image
return QImage((uchar*)src.data, src.cols, src.rows, static_cast<int>(src.step), QImage::Format_Grayscale8).copy();
@@ -108,11 +109,11 @@ static cv::Mat qImageToCvMat(const QImage& inImage)
}
return cv::Mat();
}
static void cvMatToQPixMap(cv::Mat& src,QPixmap& pixmap)
static void cvMatToQPixMap(const cv::Mat& src,QPixmap& pixmap)
{
pixmap = QPixmap::fromImage(cvMatToQImage(src));
}
static QPixmap cvMatToQPixMap(cv::Mat& src)
static QPixmap cvMatToQPixMap(const cv::Mat& src)
{
return QPixmap::fromImage(cvMatToQImage(src));
}
@@ -169,8 +170,8 @@ static void createDirectoryIfNotExists(const std::string& path) {
}
}
static void createDirectoryIfNotExists(const QString& path) {
QDir dir;
dir.mkpath(path);
QDir dir;
dir.mkpath(path);
}
Q_DECLARE_METATYPE(cv::Mat*)
+7 -6
View File
@@ -4,6 +4,7 @@
#include <backendInterface.h>
#include <generalJsonParsing.hpp>
#include <serviceManager.h>
#include <future>
triggerManager::triggerManager(ServiceManager* _serviceManager, bSignalHub* bridgeIn,nlohmann::ordered_json& triggerJson){
bridge = bridgeIn;
@@ -161,17 +162,17 @@ void triggerManager::checkCallback(readAllStruct _struct, QByteArray& byteArray)
if (checkTrigger(callback.triggerAddress, callback.triggerValue, _struct, byteArray) == true)
{
qDebug() << "func:" << QString::fromStdString(callback.funcName) << "->已触发 " << callback.triggerValue;
std::thread([callback, byteArray]() mutable {
std::async(std::launch::async, [callback, byteArray]() mutable {
try {
callback.func(callback.triggerAddress, callback.triggerValue, byteArray); // 执行回调函数
}
catch (const std::exception& e) {
qCritical() << "Error in union callback " << QString::fromStdString(callback.funcName) << ": " << QString::fromStdString(e.what());
qCritical() << "Error in callback " << QString::fromStdString(callback.funcName) << ": " << QString::fromStdString(e.what());
}
catch (...) {
qCritical() << "Error in union callback : unexpected" << QString::fromStdString(callback.funcName);
qCritical() << "Error in callback : unexpected" << QString::fromStdString(callback.funcName);
}
}).detach();
});
}
}
}
@@ -215,7 +216,7 @@ void triggerManager::checkUnionCallback(readAllStruct& _struct, QByteArray& byte
}
}
qDebug() << "Union func:" << QString::fromStdString(cb.funcName) << "->已触发 ("<< triggerSource <<")";
std::thread([cb, copyByte = byteArray, triggerSource]() mutable {
std::async(std::launch::async, [cb, copyByte = byteArray, triggerSource]() mutable {
try {
cb.func(triggerSource, copyByte);
}
@@ -225,7 +226,7 @@ void triggerManager::checkUnionCallback(readAllStruct& _struct, QByteArray& byte
catch (...) {
qCritical() << "Error in union callback : unexpected" << QString::fromStdString(cb.funcName);
}
}).detach();
});
}
}
@@ -130,7 +130,7 @@ private:
axisX = new QBarCategoryAxis();
axisX->setLabelsBrush(QBrush(Qt::white));
axisX->setLabelsAngle(-45); // 设置标签倾斜45度
axisX->setLabelsAngle(histogramLabelTiltAngle); // 设置标签倾斜
chart->addAxis(axisX, Qt::AlignBottom);
series->attachAxis(axisX);
+15 -78
View File
@@ -30,58 +30,6 @@
#include <QImage>
#include <QMetaType>
class ImageWidgetManager;
// 后台图像处理(压缩 + 颜色空间转换)线程工作对象
class ImageProcessWorker : public QObject {
Q_OBJECT
public:
explicit ImageProcessWorker(int threshold, QObject* parent = nullptr)
: QObject(parent), threshold(threshold) {}
public slots:
void process(const cv::Mat& img, const QString& type) {
if (img.empty()) return;
QImage qimg = matToQImageWithCompress(img, threshold);
emit imageReady(type, qimg);
}
signals:
void imageReady(const QString& type, const QImage& img);
private:
int threshold = 0;
QImage matToQImageWithCompress(const cv::Mat& srcIn, int thr) {
if (srcIn.empty()) return QImage();
cv::Mat src = srcIn;
while ((thr > 0) && (src.cols > thr || src.rows > thr)) {
cv::Mat half;
cv::resize(src, half, cv::Size(src.cols / 2, src.rows / 2), 0, 0, cv::INTER_AREA);
src = half;
}
cv::Mat display;
QImage img;
switch (src.type()) {
case CV_8UC3:
cv::cvtColor(src, display, cv::COLOR_BGR2RGB);
img = QImage(display.data, display.cols, display.rows, display.step, QImage::Format_RGB888).copy();
break;
case CV_8UC1:
img = QImage(src.data, src.cols, src.rows, src.step, QImage::Format_Grayscale8).copy();
break;
case CV_8UC4:
cv::cvtColor(src, display, cv::COLOR_BGRA2RGBA);
img = QImage(display.data, display.cols, display.rows, display.step, QImage::Format_RGBA8888).copy();
break;
default:
src.convertTo(display, CV_8UC3);
cv::cvtColor(display, display, cv::COLOR_BGR2RGB);
img = QImage(display.data, display.cols, display.rows, display.step, QImage::Format_RGB888).copy();
break;
}
return img;
}
};
//单画幅
class SonGraphicsView : public QGraphicsView{
public:
@@ -98,8 +46,8 @@ public:
setInteractive(false);
setEnabled(false);
setObjectName("SonGraphicsView");
// 缩放以鼠标位置为锚点
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
// 缩放以窗口中心为锚点
setTransformationAnchor(QGraphicsView::AnchorViewCenter);
setResizeAnchor(QGraphicsView::AnchorViewCenter);
//scene->addItem(rectGroup);
@@ -313,7 +261,15 @@ private:
// 需要应用的相对缩放
double apply = target / cur;
if (std::abs(apply - 1.0) < 1e-6) return;
// 获取视图中心点在场景中的坐标
QPointF centerPoint = mapToScene(viewport()->rect().center());
// 应用缩放
scale(apply, apply);
// 重新居中到原来的中心点,保持视图中心不变
centerOn(centerPoint);
}
void centerOnImageCenter() {
@@ -375,7 +331,6 @@ public:
int originalColumnSpan = 1;
ImageWidget(QWidget* parent = nullptr) : QWidget(parent) {
qRegisterMetaType<cv::Mat>("cv::Mat");
QVBoxLayout* layout = new QVBoxLayout(this);
setObjectName("ImageWidget");
setStyleSheet(R"(
@@ -461,19 +416,8 @@ public:
//setContextMenuPolicy(Qt::CustomContextMenu);
//(this, &QWidget::customContextMenuRequested, this, &ImageWidget::showContextMenu);
// 后台线程初始化
workerThread = new QThread(this);
worker = new ImageProcessWorker(uiShowImgCompressThreshold);
worker->moveToThread(workerThread);
connect(this, &ImageWidget::requestProcess, worker, &ImageProcessWorker::process, Qt::QueuedConnection);
connect(worker, &ImageProcessWorker::imageReady, this, &ImageWidget::onImageReady, Qt::QueuedConnection);
workerThread->start();
}
~ImageWidget(){
if (workerThread) {
workerThread->quit();
workerThread->wait();
}
}
void setTitle(const QString& text) {
label->setText(text);
@@ -550,7 +494,7 @@ public slots:
//void showImgOnGraphicsView(QPixmap imageMat) {
// viewer->setImg(imageMat);
//}
void accpectImg(cv::Mat img, QString type){
void accpectImg(const cv::Mat& img, QString type){
auto& it = map.find(type);
if (it == map.end())
{
@@ -559,12 +503,9 @@ public slots:
qDebug() << u8"未找到对应的viewer,输入:" << type << u8" 现有:" << listName;
return;
}
// 异步处理(仅发送到后台线程)
emit requestProcess(img, type);
}
void onImageReady(const QString& type, const QImage& qimg) {
if (qimg.isNull()) return;
QPixmap px = QPixmap::fromImage(qimg);
// 同步处理图像
if (img.empty()) return;
QPixmap px = cvMatToQPixMap(img);
{
QMutexLocker locker(&mapMutex);
map[type] = px;
@@ -574,7 +515,7 @@ public slots:
}
else if (type == "null") {
viewer->setImg(px);
}
}
}
//缩放
@@ -679,8 +620,6 @@ private:
SonGraphicsView* viewer;
QMap<QString,QPixmap> map;
QMutex mapMutex;
QThread* workerThread = nullptr;
ImageProcessWorker* worker = nullptr;
// 压缩: 如果任一边 > threshold 则按 1/2 缩,循环直到满足
QPixmap matToQPixmapWithCompress(const cv::Mat& srcIn, int threshold) {
if (srcIn.empty()) return QPixmap();
@@ -713,8 +652,6 @@ private:
return QPixmap::fromImage(std::move(img));
}
int uiShowImgCompressThreshold = 5000; // 超过该宽或高就压缩
signals:
void requestProcess(const cv::Mat& img, const QString& type);
};
//总
@@ -16,14 +16,14 @@ bool ALGO_maJiaReRong(std::shared_ptr <detData> data, maJiaParam* _detParams, sx
return false;
}
auto sourceImg = data->getOriImg(0);
//switch (address.triggerValue) {
//case 1:
// sourceImg = cv::imread("D:\\testImage\\601\\majia (1).bmp", -1);
// break;
//case 2:
// sourceImg = cv::imread("D:\\testImage\\601\\majia (2).bmp", -1);
// break;
//}
switch (address.triggerValue) {
case 1:
sourceImg = cv::imread("D:\\testImage\\601\\majia (1).bmp", -1);
break;
case 2:
sourceImg = cv::imread("D:\\testImage\\601\\majia (2).bmp", -1);
break;
}
sourceImg(cv::Rect(1700, 700, 2200, 2200)).copyTo(sourceImg);
if (sourceImg.rows == 100) {
cv::Mat Paint;
@@ -269,7 +269,7 @@ bool ALGO_dingGaiKeMa(std::shared_ptr <detData> data, keMaParam* _detParams, sx_
return false;
}
auto sourceImg = data->getOriImg(0);
/* switch (address.triggerValue) {
switch (address.triggerValue) {
case 1:
sourceImg = cv::imread("D:\\testImage\\601\\fbf (1).png", -1);
break;
@@ -279,7 +279,7 @@ bool ALGO_dingGaiKeMa(std::shared_ptr <detData> data, keMaParam* _detParams, sx_
case 3:
sourceImg = cv::imread("D:\\testImage\\601\\fbf (3).png", -1);
break;
}*/
}
if (sourceImg.rows == 100) {
cv::Mat Paint;
sourceImg.copyTo(Paint);