Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 55 additions & 24 deletions src/view/imageview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
#include <QMessageBox>
#include <QThreadPool>
#include <qmath.h>
#include <QObject>

Check warning on line 16 in src/view/imageview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QObject> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QGestureEvent>

Check warning on line 17 in src/view/imageview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QGestureEvent> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QPinchGesture>

Check warning on line 18 in src/view/imageview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QPinchGesture> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QTimer>

Check warning on line 19 in src/view/imageview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QTimer> not found. Please note: Cppcheck does not need standard library headers to get proper results.

const qreal MAX_SCALE_FACTOR = 20.0;
const qreal MIN_SCALE_FACTOR = 0.029;
Expand All @@ -32,6 +33,11 @@
this->grabGesture(Qt::PinchGesture);
setAttribute(Qt::WA_AcceptTouchEvents);
viewport()->setCursor(Qt::ArrowCursor);

m_wheelTimer = new QTimer(this);
m_wheelTimer->setSingleShot(true);
m_wheelTimer->setInterval(50);
connect(m_wheelTimer, &QTimer::timeout, this, &ImageView::onWheelTimerTimeout);
}

ImageView::~ImageView()
Expand Down Expand Up @@ -243,12 +249,41 @@

void ImageView::wheelEvent(QWheelEvent *event)
{
qreal factor = qPow(1.2, event->delta() / 240.0);
scaleAtPoint(event->pos(), factor);
const int delta = event->angleDelta().y();
if (delta == 0) {
event->accept();
return;
}

// Accumulate wheel events and defer the repaint to a timer to avoid
// per-event full repaint that overloads weak GPUs.
m_accumulatedFactor *= qPow(1.2, delta / 240.0);
m_wheelPos = event->position().toPoint();

if (!m_isZooming) {
m_isZooming = true;
if (m_pixmapItem)
m_pixmapItem->setTransformationMode(Qt::FastTransformation);
}
m_wheelTimer->start();

event->accept();
}

void ImageView::onWheelTimerTimeout()
{
if (!m_isZooming)
return;

scaleAtPoint(m_wheelPos, m_accumulatedFactor);
m_accumulatedFactor = 1.0;
m_isZooming = false;

// Restore smooth rendering once the zoom interaction settles.
if (m_pixmapItem)
m_pixmapItem->setTransformationMode(Qt::SmoothTransformation);
}

void ImageView::handleGestureEvent(QGestureEvent *gesture)
{
qDebug() << "------" << __FUNCTION__ << "";
Expand All @@ -271,9 +306,14 @@
}
void ImageView::scaleAtPoint(QPoint pos, qreal factor)
{
if (!qIsFinite(factor) || factor <= 0.0)
return;

// Remember zoom anchor point.
const QPointF targetPos = pos;
const QPointF targetScenePos = mapToScene(targetPos.toPoint());
if (!qIsFinite(targetScenePos.x()) || !qIsFinite(targetScenePos.y()))
return;

// Do the scaling.
setScaleValue(factor);
Expand All @@ -285,38 +325,29 @@
const QPointF curPos = mapFromScene(targetScenePos);
const QPointF centerPos = QPointF(width() / 2.0, height() / 2.0) + (curPos - targetPos);
const QPointF centerScenePos = mapToScene(centerPos.toPoint());
if (!qIsFinite(centerScenePos.x()) || !qIsFinite(centerScenePos.y()))
return;
centerOn(static_cast<int>(centerScenePos.x()), static_cast<int>(centerScenePos.y()));
}
void ImageView::setScaleValue(qreal v)
{
//由于矩阵被旋转,通过矩阵获取缩放因子,计算缩放比例错误,因此记录过程中的缩放因子来判断缩放比例
// Clamp the factor before applying scale() to avoid overshoot and the
// extra repaint caused by the previous apply-then-rollback approach.
const qreal projected = m_scal * v;
if (projected < MIN_SCALE_FACTOR) {
v = MIN_SCALE_FACTOR / m_scal;
} else if (projected > MAX_SCALE_FACTOR) {
v = MAX_SCALE_FACTOR / m_scal;
}

m_scal *= v;
qDebug() << m_scal;
scale(v, v);
//const qreal irs = imageRelativeScale() * devicePixelRatioF();
// Rollback
if (v < 1 && /*irs <= MIN_SCALE_FACTOR)*/m_scal < 0.03) {
const qreal minv = MIN_SCALE_FACTOR / m_scal;
// if (minv < 1.09) return;
scale(minv, minv);
m_scal *= minv;
} else if (v > 1 && /*irs >= MAX_SCALE_FACTOR*/m_scal > 20) {
const qreal maxv = MAX_SCALE_FACTOR / m_scal;
scale(maxv, maxv);
m_scal *= maxv;
} else {
m_isFitImage = false;
m_isFitWindow = false;
}
m_isFitImage = false;
m_isFitWindow = false;

// qreal rescale = imageRelativeScale() * devicePixelRatioF();
// if (rescale - 1 > -0.01 && rescale - 1 < 0.01) {
// emit checkAdaptImageBtn();
// } else {
// emit disCheckAdaptImageBtn();
// }
emit scaled(m_scal * 100);
emit showScaleLabel();

}

7 changes: 7 additions & 0 deletions src/view/imageview.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
#ifndef IMAGEVIEW_H
#define IMAGEVIEW_H

#include <QGraphicsView>

Check warning on line 11 in src/view/imageview.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QGraphicsView> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QTimer>

Check warning on line 12 in src/view/imageview.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QTimer> not found. Please note: Cppcheck does not need standard library headers to get proper results.

class QGraphicsPixmapItem;
class QGestureEvent;
Expand Down Expand Up @@ -61,6 +62,8 @@
signals:
void scaled(qreal perc);
void showScaleLabel();
private slots:
void onWheelTimerTimeout();
private:
QString m_currentPath;//当前图片路径
QGraphicsPixmapItem *m_pixmapItem{nullptr};//当前图像的item
Expand All @@ -71,6 +74,10 @@
QImage *m_currentImage{nullptr};//当前原始图像
QImage m_FilterImage{nullptr};//当前处理的图像
QImage m_lightContrastImage{nullptr};//亮度曝光度图像
QTimer *m_wheelTimer{nullptr};
qreal m_accumulatedFactor = 1.0;
QPoint m_wheelPos;
bool m_isZooming = false;

};

Expand Down
Loading