#include "image_view.h" #include #include #include #include #include #include #include #include #include ImageView::ImageView(QWidget * parent): QGraphicsView(parent), item(new QGraphicsPixmapItem) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setDragMode(QGraphicsView::NoDrag); setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setScene(new QGraphicsScene()); setRenderHint(QPainter::Antialiasing, true); setRenderHint(QPainter::SmoothPixmapTransform, true); item->setTransformationMode(Qt::SmoothTransformation); item->setFlags(QGraphicsItem::GraphicsItemFlags()); scene()->addItem(item); viewport()->setAutoFillBackground(false); viewport()->installEventFilter(this); autofit_ = smooth_big = true; interactive_ = false; } ImageView::~ImageView() { auto os = scene(); setScene(nullptr); delete os; } QPixmap ImageView::pixmap() const { return map; } void ImageView::setPixmap(QPixmap pixmap) { map = pixmap; adjustView(); } void ImageView::setViewInteractive(bool yes) { interactive_ = yes; } void ImageView::setImage(const QImage & i, bool save) { im_data.clear(); if (i.isNull()) { item->setPixmap(QPixmap()); map = QPixmap(); return; } if (save) { QBuffer b(&im_data); b.open(QIODevice::ReadWrite); i.save(&b, "png"); b.close(); } map = QPixmap::fromImage(i); adjustView(); } void ImageView::setImage(const QByteArray & i) { im_data = i; if (i.isEmpty()) { item->setPixmap(QPixmap()); map = QPixmap(); return; } map = QPixmap::fromImage(QImage::fromData(i)); adjustView(); } void ImageView::clear() { im_data.clear(); item->setPixmap(QPixmap()); map = QPixmap(); } void ImageView::setSmoothBigImages(bool yes) { smooth_big = yes; adjustView(); } void ImageView::mouseDoubleClickEvent(QMouseEvent *) { autofit(); } void ImageView::mousePressEvent(QMouseEvent * e) { QGraphicsView::mousePressEvent(e); emit clicked(mapToScene(e->pos()), e->buttons()); } void ImageView::mouseMoveEvent(QMouseEvent * e) { QGraphicsView::mouseMoveEvent(e); emit hovered(mapToScene(e->pos()), e->buttons()); } void ImageView::mouseReleaseEvent(QMouseEvent * e) { QGraphicsView::mouseReleaseEvent(e); emit released(mapToScene(e->pos()), e->buttons()); } void ImageView::wheelEvent(QWheelEvent * e) { if (!e->modifiers().testFlag(Qt::ControlModifier) || !viewInteractive()) return; double scl = 1. + e->angleDelta().y() / 500.; autofit_ = false; scale(scl, scl); } bool ImageView::eventFilter(QObject * o, QEvent * e) { QMouseEvent * me = reinterpret_cast(e); switch (e->type()) { case QEvent::Resize: adjustView(); break; case QEvent::MouseButtonPress: prev_pos = me->pos(); if (me->buttons().testFlag(Qt::RightButton) && !autofit_ && viewInteractive()) viewport()->setCursor(Qt::ClosedHandCursor); break; case QEvent::MouseButtonRelease: viewport()->unsetCursor(); prev_pos = me->pos(); break; case QEvent::MouseMove: if (me->buttons().testFlag(Qt::RightButton) && !autofit_ && viewInteractive()) { QPoint dp = QPoint(me->pos() - prev_pos); horizontalScrollBar()->setValue(horizontalScrollBar()->value() - dp.x()); verticalScrollBar()->setValue(verticalScrollBar()->value() - dp.y()); prev_pos = me->pos(); } break; default: break; } return QGraphicsView::eventFilter(o, e); } void ImageView::adjustView() { item->setScale(1.); if (smooth_big) { QSize ws = size(); #if QT_VERSION_MAJOR >= 5 ws *= devicePixelRatio(); #endif int nw = map.size().boundedTo(ws).width(); if (nw > 0) { qreal mp = map.width() / nw; if (mp > 1.) { QSize ss = map.size(); item->setPixmap(map.scaled(map.size() / mp, Qt::KeepAspectRatio, Qt::SmoothTransformation)); item->setScale(double(ss.width()) / item->pixmap().width()); } else item->setPixmap(map); } else item->setPixmap(map); } else item->setPixmap(map); if (!autofit_) return; QRectF r = item->mapRectToScene(item->boundingRect()); setSceneRect(r); fitInView(r, Qt::KeepAspectRatio); centerOn(r.center()); } void ImageView::autofit() { autofit_ = true; adjustView(); }