Files
handleaiuinew/HanddleAI/HandleAiUi-new/uiModule/uiModule_imageView.h
T

468 lines
14 KiB
C++
Raw Normal View History

2024-05-18 23:53:26 +08:00
#pragma once
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QPixmap>
#include <QWheelEvent>
#include <QKeyEvent>
#include <opencv.hpp>
#include <QMenu>
#include <QAction>
#include <qmessagebox.h>
#include <qmutex.h>
#include <uiModule/components/fancyButton.h>
#include "qscrollbar.h"
#include "globalStruct.h"
static QImage cvMatToQImage(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();
}
if (src.channels() == 3) { // if 3 channel color image
cv::Mat rgbMat;
cv::cvtColor(src, rgbMat, cv::COLOR_BGR2RGB); // invert BGR to RGB
return QImage((uchar*)rgbMat.data, src.cols, src.rows, static_cast<int>(src.step), QImage::Format_RGB888).copy();
}
return QImage();
}
static cv::Mat qImageToCvMat(const QImage& inImage)
{
switch (inImage.format())
{
case QImage::Format_RGB32:
case QImage::Format_RGB888:
{
QImage swapped = inImage;
if (inImage.format() == QImage::Format_RGB32)
{
swapped = swapped.convertToFormat(QImage::Format_RGB888);
}
cv::Mat matImg = cv::Mat(swapped.height(), swapped.width(),
CV_8UC3,
const_cast<uchar*>(swapped.bits()),
static_cast<size_t>(swapped.bytesPerLine())
);
cv::cvtColor(matImg, matImg, cv::COLOR_RGB2BGR);
return matImg.clone();
}
case QImage::Format_Indexed8:
{
cv::Mat mat(inImage.height(), inImage.width(),
CV_8UC1,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);
return mat.clone();
}
default:
break;
}
return cv::Mat();
}
class SonGraphicsView :
public QGraphicsView
{
//Q_OBJECT
public:
QGraphicsScene* scene;
SonGraphicsView()
{
//scene = new QGraphicsScene();
//this->setScene(scene);
setDragMode(QGraphicsView::DragMode::NoDrag);
setInteractive(false);
setEnabled(false);
this->setStyleSheet("QGraphicsView {"
"background: transparent;"
"background-image: url(:/topBar/icon/waitting.png);"
"background-repeat: no-repeat;"
"background-position: center center;"
"background-size: contain;"
"}");
initShow();
this->setBackgroundBrush(QBrush(QColor(0, 0, 0)));
}
void setQImage(QImage image)
{
if (image.isNull())
return;
m_image = QPixmap::fromImage(image);
initShow();
}
void setMatImage(cv::Mat src)
{
if (src.empty())
return;
m_image = QPixmap::fromImage(cvMatToQImage(src));
initShow();
}
void setPixmap(QPixmap pixmap)
{
m_image = pixmap.copy();
initShow();
}
void resetImage()
{
if (m_image.isNull())
return;
scene->clear();
setEnabled(false);
}
QImage getQImage()
{
return m_image.toImage();
}
cv::Mat getMatImage()
{
return qImageToCvMat(m_image.toImage());
}
QPixmap getPixmap()
{
return m_image;
}
protected:
virtual void wheelEvent(QWheelEvent* event) override
{
if (m_image.isNull())
return;
QPoint numDegrees = event->angleDelta() / 8;
if (!numDegrees.isNull()) {
QPoint numSteps = numDegrees / 15;
zoom(numSteps);
}
event->accept();
}
virtual void keyPressEvent(QKeyEvent* event) override
{
if (event->key() == Qt::Key_O) {
this->resetTransform();
this->setSceneRect(m_image.rect());
this->fitInView(QRect(0, 0, m_image.width(), m_image.height()), Qt::KeepAspectRatio);
}
}
virtual void mousePressEvent(QMouseEvent* event) override
{
if (event->button() == Qt::LeftButton) {
togglePan(true, event->pos());
event->accept();
return;
}
event->ignore();
}
virtual void mouseMoveEvent(QMouseEvent* event) override
{
if (m_isPan) {
pan(event->pos());
event->accept();
return;
}
event->ignore();
}
virtual void mouseReleaseEvent(QMouseEvent* event) override
{
if (event->button() == Qt::LeftButton) {
togglePan(false);
event->accept();
return;
}
event->ignore();
}
void zoom(QPoint factor)
{
QRectF FOV = this->mapToScene(this->rect()).boundingRect();
QRectF FOVImage = QRectF(FOV.left(), FOV.top(), FOV.width(), FOV.height());
float scaleX = static_cast<float>(m_image.width()) / FOVImage.width();
float scaleY = static_cast<float>(m_image.height()) / FOVImage.height();
float minScale = scaleX > scaleY ? scaleY : scaleX;
float maxScale = scaleX > scaleY ? scaleX : scaleY;
if ((factor.y() > 0 && minScale > 100) || (factor.y() < 0 && maxScale < 1)) {
return;
}
if (factor.y() > 0)
scale(1.2, 1.2);
else
scale(0.8, 0.8);
}
void togglePan(bool pan, const QPoint& startPos = QPoint())
{
if (pan) {
if (m_isPan) {
return;
}
m_isPan = true;
m_prevPan = startPos;
setCursor(Qt::ClosedHandCursor);
}
else {
if (!m_isPan) {
return;
}
m_isPan = false;
m_prevPan = QPoint(0, 0);
setCursor(Qt::ArrowCursor);
}
}
void pan(const QPoint& panTo)
{
auto hBar = horizontalScrollBar();
auto vBar = verticalScrollBar();
auto delta = panTo - m_prevPan;
m_prevPan = panTo;
hBar->setValue(hBar->value() - delta.x());
vBar->setValue(vBar->value() - delta.y());
}
void initShow()
{
setEnabled(true);
setMouseTracking(true);
#if 0
scene->clear();
scene->addPixmap(m_image);
scene->update();
this->resetTransform();
this->setSceneRect(m_image.rect());
this->fitInView(QRect(0, 0, m_image.width(), m_image.height()), Qt::KeepAspectRatio);
#endif
if(scene==nullptr)
delete scene;
scene = new QGraphicsScene;
QImage image1 = getQImage();
QPixmap pixmap = QPixmap::fromImage(image1);
if (pixmap.isNull())
return;
QGraphicsPixmapItem* pixmapItem = scene->addPixmap(pixmap);
this->setScene(scene);
this->fitInView(pixmapItem, Qt::KeepAspectRatio);
this->show();
}
private:
QPixmap m_image;
bool m_isPan;
QPoint m_prevPan;
};
class ImageWidget : public QWidget {
public:
ImageWidget(QWidget* parent = nullptr) : QWidget(parent) {
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(5, 5, 5, 5);
view = new SonGraphicsView();
this->setMaximumSize(9999, 9999);
QPalette palette;
palette.setColor(QPalette::WindowText, Qt::white);
QFont font("微软雅黑", 12, QFont::Bold);
QHBoxLayout* hLayout = new QHBoxLayout();
label = new QLabel(u8"相机1");
label->setAlignment(Qt::AlignLeft);
label->setFont(font);
label->setPalette(palette);
label2 = new QLabel(u8"原图");
label2->setAlignment(Qt::AlignLeft);
label2->setFont(font);
label2->setPalette(palette);
hLayout->addWidget(label);
hLayout->addWidget(label2);
hLayout->setContentsMargins(0, 0, 0, 0);
fancyButton* switchBtn = new fancyButton(
30,
30,
QIcon(":/topBar/icon/switch.png"),
"切换结果图与原图"
);
connect(switchBtn, &QPushButton::clicked, [=]()
{
switchOriAndRes();
});
hLayout->addWidget(switchBtn);
layout->addLayout(hLayout);
layout->addWidget(view);
view->setDragMode(QGraphicsView::ScrollHandDrag);
view->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
view->setRenderHint(QPainter::Antialiasing);
view->setRenderHint(QPainter::SmoothPixmapTransform);
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//item = new QGraphicsPixmapItem();
//scene->addItem(item);
//view->fitInView(item, Qt::KeepAspectRatio);
//view->setBackgroundBrush(QBrush(QColor(0, 0, 0)));
//QPixmap backgroundImage(".//icon//watting.png"); // 替换为你的背景图片路径
//QGraphicsPixmapItem* backgroundItem = new QGraphicsPixmapItem(backgroundImage);
//view->scene->addItem(backgroundItem);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QWidget::customContextMenuRequested, this, &ImageWidget::showContextMenu);
}
void setLabelText(const QString& text) {
label->setText(text);
}
void showOriImg(cv::Mat oriImgInput)
{
oriImg= oriImgInput;
if (MatType == false)
setImageFromMat(oriImgInput);
}
void showResImg(cv::Mat resImgInput)
{
resImg= resImgInput;
if (MatType == true)
setImageFromMat(resImg);
}
void setImageFromMat(cv::Mat imageMat) {
if (imageMat.empty()) {
return;
}
QImage img(imageMat.data, imageMat.cols, imageMat.rows, imageMat.step, QImage::Format_RGB888);
if (img.isNull()) {
return;
}
QPixmap pixmap = QPixmap::fromImage(img.rgbSwapped());
if (pixmap.isNull()) {
return;
}
//bool itemUpdated = false;
//for (QGraphicsItem* item : scene->items()) {
// QGraphicsPixmapItem* pixmapItem = dynamic_cast<QGraphicsPixmapItem*>(item);
// if (pixmapItem) {
// pixmapItem->setPixmap(pixmap);
// itemUpdated = true;
// break;
// }
//}
//if (!itemUpdated) {
// QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pixmap);
// scene->addItem(item);
//}
view->setPixmap(pixmap);
//view->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
void switchOriAndRes()//切换原图和结果图
{
if (MatType == false)
{
setImageFromMat(resImg);
label2->setText(u8"结果图");
}
else
{
setImageFromMat(oriImg);
label2->setText(u8"原图");
}
MatType = !MatType;
}
protected:
void wheelEvent(QWheelEvent* event) override {
if (event->modifiers() & Qt::ControlModifier) {
double scaleFactor = 1.15;
if (event->angleDelta().y() < 0) {
scaleFactor = 1.0 / scaleFactor;
}
view->scale(scaleFactor, scaleFactor);
event->accept();
}
else {
QWidget::wheelEvent(event);
}
}
private:
void paintEvent(QPaintEvent* event) override {
QWidget::paintEvent(event);
QPainter painter(this);
painter.setPen(QPen(Qt::white, 1));
painter.drawRect(rect().adjusted(1, 1, -2, -2));
}
void showContextMenu(const QPoint& pos) {
QMenu contextMenu(tr("Context Menu"), this);
QAction* action1 = new QAction(u8"切换原图/结果图", this);
contextMenu.addAction(action1);
QAction* selectedAction = contextMenu.exec(mapToGlobal(pos));
if (selectedAction == action1) {
switchOriAndRes();
}
}
cv::Mat oriImg;
cv::Mat resImg;
bool MatType = false;//false ori true Res
int in = 0;
QLabel* label;
QLabel* label2;
//SonGraphicsView* scene;
//QGraphicsPixmapItem* item;
SonGraphicsView* view;
};
class ImageWidgetController
{
public:
QMutex mutex;
QList< ImageWidget*>ImageWidgetList;
std::unordered_map<std::string, ImageWidget*>map;
ImageWidget* createViewer(std::string nickName = "none")
{
ImageWidget* ImageView = new ImageWidget();
ImageWidgetList.push_back(ImageView);
if (nickName != "none")
map.insert({ nickName,ImageView });
return ImageView;
}
bool showOriImg(cv::Mat img, int index)
{
if (index > ImageWidgetList.size())
return false;
if (img.channels() == 1)
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
ImageWidgetList[index]->showOriImg(img);
}
bool showResImg(cv::Mat img, int index)
{
if (index > ImageWidgetList.size())
return false;
if (img.channels() == 1)
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
ImageWidgetList[index]->showResImg(img);
}
bool showOriImg(cv::Mat img, std::string nickName)
{
if (map.find(nickName) == map.end())
return false;
if (img.channels() == 1)
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
map[nickName]->showOriImg(img);
}
bool showResImg(cv::Mat img, std::string nickName)
{
if (map.find(nickName) == map.end())
return false;
if (img.channels() == 1)
cv::cvtColor(img, img, cv::COLOR_GRAY2BGR);
map[nickName]->showResImg(img);
}
};