#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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(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(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(swapped.bits()), static_cast(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(inImage.bits()), static_cast(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(m_image.width()) / FOVImage.width(); float scaleY = static_cast(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: void showimg(cv::Mat& img) { scene->clear(); // 加载图像 cv::Mat matForQimg; cvtColor(img, matForQimg, cv::COLOR_BGR2RGB); QImage disImage = QImage((const unsigned char*)(matForQimg.data), matForQimg.cols, matForQimg.rows, QImage::Format_RGB888); QPixmap pixmap = QPixmap::fromImage(disImage); if (pixmap.isNull()) { return; } auto item = scene->addPixmap(pixmap); setSceneRect(pixmap.rect()); // 自适应缩放 fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); // 设置视图 //setFixedSize(640, 480); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setMouseTracking(true); if (rectGroup != nullptr) delete rectGroup; rectGroup = new QGraphicsItemGroup(); scene->addItem(rectGroup); } void showimg(QImage& img) { scene->clear(); // 加载图像 QPixmap pixmap = QPixmap::fromImage(img); if (pixmap.isNull()) { return; } auto item = scene->addPixmap(pixmap); setSceneRect(pixmap.rect()); // 自适应缩放 fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); // 设置视图 //setFixedSize(640, 480); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setMouseTracking(true); if (rectGroup != nullptr) delete rectGroup; rectGroup = new QGraphicsItemGroup(); scene->addItem(rectGroup); } void showimg(QPixmap& img) { scene->clear(); // 加载图像 if (img.isNull()) { return; } auto item = scene->addPixmap(img); setSceneRect(img.rect()); // 自适应缩放 fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio); // 设置视图 //setFixedSize(640, 480); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setMouseTracking(true); if (rectGroup != nullptr) delete rectGroup; rectGroup = new QGraphicsItemGroup(); scene->addItem(rectGroup); } QPixmap m_image; bool m_isPan; QPoint m_prevPan; QGraphicsItemGroup* rectGroup = nullptr; }; 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 setTitle(const QString& text) { label->setText(text); } //set不一定显示,要根据当前显示的类型决定 void setOriImg(cv::Mat oriImgInput) { if (oriImgInput.empty()) { return; } pixOriImg = QPixmap::fromImage(cvMatToQImage(oriImgInput).rgbSwapped()); if (pixOriImg.isNull()) { return; } oriImg= oriImgInput; if (MatType == false) showImg(pixOriImg); } //set不一定显示,要根据当前显示的类型决定 void setResImg(cv::Mat resImgInput) { if (resImgInput.empty()) { return; } pixResImg = QPixmap::fromImage(cvMatToQImage(resImgInput).rgbSwapped()); if (pixResImg.isNull()) { return; } resImg = resImgInput; if (MatType == true) showImg(pixResImg); } //set不一定显示,要根据当前显示的类型决定 void setOriImg(QPixmap oriImgInput) { pixOriImg = oriImgInput; if (pixOriImg.isNull()) { return; } if (MatType == false) showImg(pixOriImg); } //set不一定显示,要根据当前显示的类型决定 void setResImg(QPixmap resImgInput) { pixResImg = resImgInput; if (pixResImg.isNull()) { return; } if (MatType == true) showImg(pixResImg); } //无视当前类型直接显示 void showImg(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; } view->setPixmap(pixmap); } void showImg(QPixmap& imageMat) { view->setPixmap(imageMat); } void switchOriAndRes()//切换原图和结果图 { if (MatType == false) { if(pixOriImg.isNull()) showImg(resImg); else showImg(pixResImg); label2->setText(u8"结果图"); } else { if (pixOriImg.isNull()) showImg(oriImg); else showImg(pixOriImg); 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; QPixmap pixOriImg; QPixmap pixResImg; bool MatType = false;//false ori true Res int in = 0; QLabel* label; QLabel* label2; //SonGraphicsView* scene; //QGraphicsPixmapItem* item; SonGraphicsView* view; }; class ImageWidgetController :public QWidget { public: QGridLayout* Layout = new QGridLayout(); ImageWidgetController() { this->setLayout(Layout); Layout->setContentsMargins(0, 0, 0, 0); } ImageWidget* createViewer(QString nickName = "none") { ImageWidget* ImageView = new ImageWidget(); ImageWidgetList.push_back(ImageView); if (nickName != "none") map.insert({ nickName,ImageView }); ImageView->setTitle(nickName); Layout->addWidget(ImageView); return ImageView; } QMutex mutex; QList< ImageWidget*>ImageWidgetList; std::unordered_mapmap; bool setImg(cv::Mat img, imgWidgetShowType _type , int index) { if (index > ImageWidgetList.size()) return false; switch (_type) { case imgWidgetOri: ImageWidgetList[index]->setOriImg(img); break; case imgWidgetRes: ImageWidgetList[index]->setResImg(img); break; } } bool setImg(cv::Mat img, imgWidgetShowType _type, QString nickName) { if (map.find(nickName) == map.end()) return false; switch (_type) { case imgWidgetOri: map[nickName]->setOriImg(img); break; case imgWidgetRes: map[nickName]->setResImg(img); break; } } bool setImg(QPixmap img, imgWidgetShowType _type, int index) { if (index > ImageWidgetList.size()) return false; switch (_type) { case imgWidgetOri: ImageWidgetList[index]->setOriImg(img); break; case imgWidgetRes: ImageWidgetList[index]->setResImg(img); break; } } bool setImg(QPixmap img, imgWidgetShowType _type, QString nickName) { if (map.find(nickName) == map.end()) return false; switch (_type) { case imgWidgetOri: map[nickName]->setOriImg(img); break; case imgWidgetRes: map[nickName]->setResImg(img); break; } } };