From 30c8f6557f44486f3f47eb40b8421c08d6def126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Thu, 14 May 2020 22:42:39 +0200 Subject: [PATCH] Working scale and zoom --- image.frag | 22 +++++++- image.vert | 3 +- imagescrollareagl.cpp | 118 +++++++++++++++++++++++++++++++++++++++--- imagescrollareagl.h | 15 +++++- mainwindow.cpp | 9 ++-- stretchpanel.cpp | 6 +++ stretchpanel.h | 1 + tenmon.pro | 4 +- 8 files changed, 161 insertions(+), 17 deletions(-) diff --git a/image.frag b/image.frag index 911853d..4262e9a 100644 --- a/image.frag +++ b/image.frag @@ -3,11 +3,31 @@ uniform sampler2D qt_Texture0; varying vec2 qt_TexCoord0; uniform vec2 scale; - +uniform float a; +uniform int stretch; void main(void) { vec4 color = texture2D(qt_Texture0, qt_TexCoord0); + + switch(stretch) + { + case 0: + break; + case 1: + color = sqrt(color); + break; + case 2: + color = pow(color, vec4(a)); + break; + case 3: + color = log(a*color + 1.0) / log(vec4(a+1)); + break; + case 4: + color = asinh(color / a) / asinh(1 / a); + break; + } + color = color*scale.x + scale.y; //float color = pow(c, 0.4545); gl_FragColor = color; diff --git a/image.vert b/image.vert index 002c7e7..0f88701 100644 --- a/image.vert +++ b/image.vert @@ -6,6 +6,7 @@ attribute vec2 qt_MultiTexCoord0; varying vec2 qt_TexCoord0; uniform vec2 viewport; uniform vec2 offset; +uniform float zoom; void main(void) { @@ -13,5 +14,5 @@ void main(void) vec2 scale = viewport / texSize; vec2 offsetRel = offset / texSize; gl_Position = vec4(qt_Vertex, 0.0, 1.0); - qt_TexCoord0 = qt_MultiTexCoord0 * scale + offsetRel; + qt_TexCoord0 = (qt_MultiTexCoord0 * scale + offsetRel) * zoom; } diff --git a/imagescrollareagl.cpp b/imagescrollareagl.cpp index a5ed712..c2f67ca 100644 --- a/imagescrollareagl.cpp +++ b/imagescrollareagl.cpp @@ -6,6 +6,25 @@ #include #include +void setScrollRange(QScrollBar *scrollBar, int newRange) +{ + int page = scrollBar->pageStep(); + int pos = scrollBar->value() + page/2; + int range = scrollBar->maximum() + page; + float relPos = (float)pos/(float)range; + + scrollBar->setRange(0, newRange - page); + scrollBar->setValue(relPos*newRange - page/2); +} + +void setRelativePos(QScrollBar *scrollBar, float relPos) +{ + int page = scrollBar->pageStep(); + int pos = scrollBar->value()+page/2; + int range = scrollBar->maximum()+page; + scrollBar->setValue(pos); +} + ImageWidget::ImageWidget(QWidget *parent) : QOpenGLWidget(parent) { setFocusPolicy(Qt::ClickFocus); @@ -13,6 +32,8 @@ ImageWidget::ImageWidget(QWidget *parent) : QOpenGLWidget(parent) m_low = 0; m_high = 1; m_dx = m_dy = 0; + m_scale = 1.0f; + m_blockRepaint = false; } ImageWidget::~ImageWidget() @@ -60,32 +81,64 @@ void ImageWidget::setImage(const QPixmap &pixmap) repaint(); } +void ImageWidget::setScale(float scale) +{ + m_scale = scale; + update(); +} + +void ImageWidget::blockRepaint(bool block) +{ + m_blockRepaint = block; + if(!block)update(); +} + void ImageWidget::setLow(int low) { m_low = low/m_range; - repaint(); + update(); } void ImageWidget::setHigh(int high) { m_high = high/m_range; - repaint(); + update(); +} + +void ImageWidget::setStrech(int stretch) +{ + m_stretch = stretch; + update(); } void ImageWidget::setOffset(int dx, int dy) { m_dx = dx; m_dy = dy; - repaint(); + update(); } void ImageWidget::paintGL() { + if(m_blockRepaint)return; + qDebug() << "PAINT"; + + float dx = m_dx; + float dy = m_dy; + qDebug() << "dxy" << dx << dy; + if(width() > m_image->width()*m_scale) + dx = -width()*0.5f + m_image->width()*m_scale*0.5f; + if(height() > m_image->height()*m_scale) + dy = -height()*0.5f + m_image->height()*m_scale*0.5f; + float s = 1.0f/(m_high-m_low); m_program->bind(); m_program->setUniformValue("scale", s, -m_low*s); m_program->setUniformValue("viewport", (float)width(), (float)height()); - m_program->setUniformValue("offset", m_dx, m_dy); + m_program->setUniformValue("offset", dx, dy); + m_program->setUniformValue("stretch", m_stretch); + m_program->setUniformValue("a", 0.1f); + m_program->setUniformValue("zoom", 1.0f/m_scale); m_image->bind(0); f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -149,7 +202,8 @@ void ImageWidget::initializeGL() m_program->setUniformValue("qt_Texture0", (GLuint)0); m_program->setUniformValue("scale", 1.0f, 0.0f); - m_image = std::unique_ptr(new QOpenGLTexture(QImage("/home/nou/Obrázky/1p6yap.jpg"))); + m_image = std::unique_ptr(new QOpenGLTexture(QOpenGLTexture::Target2D)); + m_image->allocateStorage(); m_image->bind(0); m_image->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); m_image->setMagnificationFilter(QOpenGLTexture::Linear); @@ -167,6 +221,7 @@ ImageScrollAreaGL::ImageScrollAreaGL(QWidget *parent) m_verticalScrollBar = new QScrollBar(Qt::Vertical, this); m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this); + m_scale = 1.0f; layout->setSpacing(0); layout->addWidget(m_imageWidget, 0, 0); @@ -203,10 +258,18 @@ ImageWidget *ImageScrollAreaGL::imageWidget() return m_imageWidget; } -void ImageScrollAreaGL::updateScrollbars() +void ImageScrollAreaGL::updateScrollbars(bool zoom) { - m_verticalScrollBar->setRange(0, m_imgHeight-m_verticalScrollBar->pageStep()); - m_horizontalScrollBar->setRange(0, m_imgWidth-m_horizontalScrollBar->pageStep()); + if(zoom) + { + setScrollRange(m_verticalScrollBar, m_imgHeight*m_scale); + setScrollRange(m_horizontalScrollBar, m_imgWidth*m_scale); + } + else + { + m_verticalScrollBar->setRange(0, m_imgHeight*m_scale - m_verticalScrollBar->pageStep()); + m_horizontalScrollBar->setRange(0, m_imgWidth*m_scale - m_horizontalScrollBar->pageStep()); + } } void ImageScrollAreaGL::resizeEvent(QResizeEvent *event) @@ -231,6 +294,45 @@ void ImageScrollAreaGL::mousePressEvent(QMouseEvent *event) m_lastPos = event->pos(); } +void ImageScrollAreaGL::wheelEvent(QWheelEvent *event) +{ + if(event->angleDelta().y() > 0) + zoomIn(); + else + zoomOut(); +} + +void ImageScrollAreaGL::zoomIn() +{ + if(m_scale >= 8.0f)return; + m_scale += 0.1f; + m_imageWidget->blockRepaint(true); + m_imageWidget->setScale(m_scale); + updateScrollbars(true); + m_imageWidget->blockRepaint(false); +} + +void ImageScrollAreaGL::zoomOut() +{ + if(m_scale <= 0.1f)return; + m_scale -= 0.1f; + m_imageWidget->blockRepaint(true); + m_imageWidget->setScale(m_scale); + updateScrollbars(true); + m_imageWidget->blockRepaint(false); + //m_imageWidget->repaint(); +} + +void ImageScrollAreaGL::bestFit() +{ + +} + +void ImageScrollAreaGL::oneToOne() +{ + +} + void ImageScrollAreaGL::scrollEvent() { qDebug() << m_horizontalScrollBar->value() << m_verticalScrollBar->value(); diff --git a/imagescrollareagl.h b/imagescrollareagl.h index b2eedbb..077f232 100644 --- a/imagescrollareagl.h +++ b/imagescrollareagl.h @@ -33,16 +33,22 @@ class ImageWidget : public QOpenGLWidget int m_width, m_height; float m_low; float m_high; + int m_stretch; float m_range; float m_dx, m_dy; + float m_scale; + bool m_blockRepaint; public: explicit ImageWidget(QWidget *parent = nullptr); ~ImageWidget(); void setImage(RawImage *image); void setImage(const QPixmap &pixmap); + void setScale(float scale); + void blockRepaint(bool block); public slots: void setLow(int low); void setHigh(int high); + void setStrech(int stretch); void setOffset(int dx, int dy); protected: void paintGL(); @@ -58,6 +64,7 @@ class ImageScrollAreaGL : public QWidget ImageWidget *m_imageWidget; int m_imgWidth, m_imgHeight; QPoint m_lastPos; + float m_scale; public: explicit ImageScrollAreaGL(QWidget *parent = nullptr); ~ImageScrollAreaGL(); @@ -65,10 +72,16 @@ public: void setImage(const QPixmap &pixmap); ImageWidget* imageWidget(); protected: - void updateScrollbars(); + void updateScrollbars(bool zoom = false); void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); +public slots: + void zoomIn(); + void zoomOut(); + void bestFit(); + void oneToOne(); protected slots: void scrollEvent(); }; diff --git a/mainwindow.cpp b/mainwindow.cpp index 521367d..f8d70dc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -51,6 +51,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) StretchPanel *stretchPanel = new StretchPanel(this); connect(stretchPanel, SIGNAL(lowChanged(int)), m_imageGL->imageWidget(), SLOT(setLow(int))); connect(stretchPanel, SIGNAL(highChanged(int)), m_imageGL->imageWidget(), SLOT(setHigh(int))); + connect(stretchPanel, SIGNAL(stretchChanged(int)), m_imageGL->imageWidget(), SLOT(setStrech(int))); QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this); stretchDock->setWidget(stretchPanel); @@ -73,10 +74,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) menuBar()->addMenu(fileMenu); QMenu *viewMenu = new QMenu(tr("View"), this); - viewMenu->addAction(tr("Zoom In"), m_image, SLOT(zoomIn()), QKeySequence::ZoomIn); - viewMenu->addAction(tr("Zoom Out"), m_image, SLOT(zoomOut()), QKeySequence::ZoomOut); - viewMenu->addAction(tr("Best Fit"), m_image, SLOT(bestFit()), QKeySequence("Ctrl+1")); - viewMenu->addAction(tr("100%"), m_image, SLOT(oneToOne())); + viewMenu->addAction(tr("Zoom In"), m_imageGL, SLOT(zoomIn()), QKeySequence::ZoomIn); + viewMenu->addAction(tr("Zoom Out"), m_imageGL, SLOT(zoomOut()), QKeySequence::ZoomOut); + viewMenu->addAction(tr("Best Fit"), m_imageGL, SLOT(bestFit()), QKeySequence("Ctrl+1")); + viewMenu->addAction(tr("100%"), m_imageGL, SLOT(oneToOne())); menuBar()->addMenu(viewMenu); QMenu *selectMenu = new QMenu(tr("Select"), this); diff --git a/stretchpanel.cpp b/stretchpanel.cpp index 4a8eff6..b09ada7 100644 --- a/stretchpanel.cpp +++ b/stretchpanel.cpp @@ -1,5 +1,6 @@ #include "stretchpanel.h" #include +#include StretchPanel::StretchPanel(QWidget *parent) : QWidget(parent) { @@ -13,9 +14,14 @@ StretchPanel::StretchPanel(QWidget *parent) : QWidget(parent) m_highSlider->setRange(0, UINT16_MAX); m_highSlider->setValue(UINT16_MAX); + QComboBox *stretchSelect = new QComboBox(this); + stretchSelect->addItems({tr("Linear"), tr("Square root"), tr("Power"), tr("Logarithm"), tr("Asinh")}); + layout->addWidget(m_lowSlider); layout->addWidget(m_highSlider); + layout->addWidget(stretchSelect); connect(m_lowSlider, SIGNAL(valueChanged(int)), this, SIGNAL(lowChanged(int))); connect(m_highSlider, SIGNAL(valueChanged(int)), this, SIGNAL(highChanged(int))); + connect(stretchSelect, SIGNAL(activated(int)), this, SIGNAL(stretchChanged(int))); } diff --git a/stretchpanel.h b/stretchpanel.h index 86ac37a..9b8b42a 100644 --- a/stretchpanel.h +++ b/stretchpanel.h @@ -14,6 +14,7 @@ public: signals: void lowChanged(int low); void highChanged(int high); + void stretchChanged(int stretch); }; #endif // STRETCHPANEL_H diff --git a/tenmon.pro b/tenmon.pro index 2c2ebd4..4bc5b9c 100644 --- a/tenmon.pro +++ b/tenmon.pro @@ -6,7 +6,7 @@ QT += core gui sql network -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets opengl TARGET = tenmon TEMPLATE = app @@ -16,7 +16,7 @@ CONFIG += c++11 QMAKE_CXXFLAGS += -fopenmp unix: CONFIG += link_pkgconfig -unix: PKGCONFIG += libraw_r cfitsio gsl libexif opencv +unix: PKGCONFIG += libraw_r cfitsio gsl libexif opencv4 win32:LIBS += -lraw -lexif -lcfitsio -lgsl -lgslcblas -lopencv_imgproc -lopencv_core -fopenmp win32:LIBS += -LC:\msys64\mingw64\lib -LC:\msys64\mingw64\bin