Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Cursor and image coordinates(problem with scaling)
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Cursor and image coordinates(problem with scaling)

Scheduled Pinned Locked Moved General and Desktop
11 Posts 3 Posters 16.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    giesbert
    wrote on last edited by
    #2

    Hi Anticross,

    Make x and y doubles

    make m_scaleFactor a double with 1.0 = 100 %

    make m_scaleFactor > 1.0 zoomed in and < 1.0 scaled out and use:

    @
    x *= m_scaleFactor;
    y *= m_scaleFactor;
    @

    Nokia Certified Qt Specialist.
    Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Anticross
      wrote on last edited by
      #3

      I modified it and now it looks like this:
      @void ImageWidget::mousePressEvent( QMouseEvent * event )
      {
      double x = event->pos().x();
      double y = event->pos().y();

      // Calculate scale and image sizes
      double h = m_imageLabel->height();
      double w = m_imageLabel->width();

      if(x>w || y>h)
      return;

      if(h>size().height() || w>size().width())
      {
      m_scaleFactor = 1.0;
      }

      x *= m_scaleFactor;
      y *= m_scaleFactor;

      QRgb pixel = m_image.pixel(x,y);

      QColor color = QColor::fromRgb(pixel);

      }@ but I still have wrong coords(sometimes with some offset from right coords).

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Anticross
        wrote on last edited by
        #4

        The whole source of ImageViever class is
        *.cpp:
        @#include "ImageWidget.h"

        //-----------------------------------------------------------------------------
        ImageWidget::ImageWidget( QWidget * parent, const QString & filename ) : QWidget(parent)
        {
        m_imageLabel = new QLabel();
        m_imageLabel->setBackgroundRole(QPalette::Base);
        m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        m_imageLabel->setScaledContents(true);

        m_scrollArea = new QScrollArea(this);
        m_scrollArea->setBackgroundRole(QPalette::Dark);
        m_scrollArea->setWidget(m_imageLabel);

        QVBoxLayout * layout = new QVBoxLayout();
        layout->addWidget(m_scrollArea);
        setLayout(layout);

        setWindowTitle(filename);
        resize(500, 400);

        // open file

        m_image = QImage(filename);
        if (m_image.isNull()) {
        QMessageBox::information(this, tr("Warning"),
        tr("Cannot load %1.").arg(filename));
        return;
        }

        m_imageLabel->setPixmap(QPixmap::fromImage(m_image));

        m_scaleFactor = 1.0;
        normalSize();

        m_pixelatorFlag = false;

        //connect(parent->ui.actionPixelator, SIGNAL(triggered()), this, SLOT(pixelatorOn()));
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::zoomIn()
        {

        scaleImage(1.25);
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::zoomOut()
        {
        scaleImage(0.8);
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::normalSize()
        {
        m_imageLabel->adjustSize();
        m_scaleFactor = 1.0;
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::fitToWindow( bool fitToWindow )
        {
        m_scrollArea->setWidgetResizable(fitToWindow);
        if (!fitToWindow) {
        normalSize();
        }
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::scaleImage( double factor )
        {
        Q_ASSERT(m_imageLabel->pixmap());
        m_scaleFactor *= factor;
        m_imageLabel->resize(m_scaleFactor * m_imageLabel->pixmap()->size());

        adjustScrollBar(m_scrollArea->horizontalScrollBar(), factor);
        adjustScrollBar(m_scrollArea->verticalScrollBar(), factor);
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::adjustScrollBar( QScrollBar *scrollBar, double factor )
        {
        scrollBar->setValue(int(factor * scrollBar->value()

        • ((factor - 1) * scrollBar->pageStep()/2)));
          }
          //-----------------------------------------------------------------------------
          void ImageWidget::mousePressEvent( QMouseEvent * event )
          {
          double x = event->pos().x();
          double y = event->pos().y();

        // Calculate scale and image sizes
        double h = m_imageLabel->height();
        double w = m_imageLabel->width();

        if(x>w || y>h)
        return;

        if(h>size().height() || w>size().width())
        {
        m_scaleFactor = 1.0;
        }

        x *= m_scaleFactor;
        y *= m_scaleFactor;

        QRgb pixel = m_image.pixel(x,y);

        QColor color = QColor::fromRgb(pixel);

        emit colorSelected(color.name(),x,y);

        proccessImage(color,false);
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::proccessImage(QColor color, bool inverse)
        {
        // Search algorithm

        QImage image = m_image;
        int difference = 20;

        for(int y = 0; y < image.height(); y++)
        {
        for(int x = 0; x < image.width(); x++)
        {
        QRgb currentPixel = image.pixel(x,y);

        if( qAbs(qRed(currentPixel) - color.red()) > difference &&
        qAbs(qGreen(currentPixel) - color.green()) > difference &&
        qAbs(qBlue(currentPixel) - color.blue()) > difference)
        {
        if(!inverse)
        image.setPixel(x,y,qRgb(255,255,255));
        }
        else
        {
        if(inverse)
        image.setPixel(x,y,qRgb(255,255,255));
        }
        }
        }
        m_imageLabel->setPixmap(QPixmap::fromImage(image));
        }
        //-----------------------------------------------------------------------------
        void ImageWidget::pixelatorOn()
        {
        // QAction * act = (QAction *)QObject::sender();
        //
        // if(act == NULL)
        // return;
        //
        // if(act->isChecked())
        // m_pixelatorFlag = true;
        // else
        // m_pixelatorFlag = false;
        }
        //-----------------------------------------------------------------------------
        @
        *.h:
        @#ifndef IMAGEWIDGET_H
        #define IMAGEWIDGET_H

        #include <QWidget>
        #include <QScrollBar>
        #include <QScrollArea>
        #include <QLabel>
        #include <QMessageBox>
        #include <QVBoxLayout>
        #include <QMouseEvent>
        #include <QColor>

        class ImageWidget : public QWidget
        {
        Q_OBJECT

        QLabel *m_imageLabel;
        QScrollArea *m_scrollArea;
        double m_scaleFactor;
        QImage m_image;
        bool m_pixelatorFlag;

        public:
        ImageWidget(QWidget * parent, const QString & filename);
        void zoomIn();
        void zoomOut();
        void normalSize();
        void fitToWindow(bool fitToWindow);

        private:
        void scaleImage(double factor);
        void adjustScrollBar(QScrollBar *scrollBar, double factor);
        void proccessImage(QColor color, bool inverse);

        protected:
        void mousePressEvent(QMouseEvent * event);

        public slots:
        void pixelatorOn();

        signals:
        void colorSelected(const QString & color, int x, int y);

        };

        #endif//IMAGEWIDGET_H
        @

        Maybe I miss something when editing qt example and thats why I get wrong coords ?

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #5

          You handle the mouse event with coordinates of teh ImageWidget class, but the picture is displayed in a subwidget. Map the coordinates to the label and it should work.

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • A Offline
            A Offline
            Anticross
            wrote on last edited by
            #6

            I replace 84-85 rows of my cpp file by this:

            @QPoint pos = m_imageLabel->mapFromParent(event->pos());
            double x = pos.x();
            double y = pos.y();@

            And it's worked, thx Gerolf.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Anticross
              wrote on last edited by
              #7

              Same trouble after some modificatin. When zoomOut and then make a click. Coordinates moved up left from real position, and after zoomOut its moved down right. Changed code looks like this:
              *.h
              @#ifndef IMAGEWIDGET_H
              #define IMAGEWIDGET_H

              #include <QWidget>
              #include <QScrollBar>
              #include <QScrollArea>
              #include <QLabel>
              #include <QMessageBox>
              #include <QVBoxLayout>
              #include <QMouseEvent>
              #include <QColor>
              #include <QGraphicsItem>

              enum curAction {ePixel, eErase, eNoact};

              class ImageWidget : public QWidget
              {
              Q_OBJECT

              QLabel *m_imageLabel;
              QScrollArea *m_scrollArea;
              double m_scaleFactor;
              QImage m_image;
              bool m_pixelatorFlag;
              int m_difference;
              QColor m_currentColor;
              curAction m_action;

              public:
              ImageWidget(QWidget * parent, const QString & filename);
              void zoomIn();
              void zoomOut();
              void normalSize();
              void fitToWindow(bool fitToWindow);
              void setCurrentAction(curAction action);

              private:
              void scaleImage(double factor);
              void adjustScrollBar(QScrollBar *scrollBar, double factor);
              void proccessImage(QColor color, bool inverse);
              void eraseImage(const QPointF & startPoint,const QPointF & endPoint);
              void revertChanges();

              protected:
              void mousePressEvent(QMouseEvent * event);
              void keyPressEvent (QKeyEvent * event);

              public slots:
              void onChangeDifference(int difference);

              signals:
              void colorSelected(const QString & color, int x, int y);

              };

              #endif//IMAGEWIDGET_H
              @

              1 Reply Last reply
              0
              • A Offline
                A Offline
                Anticross
                wrote on last edited by
                #8

                *.cpp
                @#include "ImageWidget.h"

                //-----------------------------------------------------------------------------
                ImageWidget::ImageWidget( QWidget * parent, const QString & filename ) : QWidget(parent)
                {
                m_imageLabel = new QLabel();
                m_imageLabel->setBackgroundRole(QPalette::Base);
                m_imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
                m_imageLabel->setScaledContents(true);

                m_scrollArea = new QScrollArea(this);
                m_scrollArea->setBackgroundRole(QPalette::Dark);
                m_scrollArea->setWidget(m_imageLabel);

                QVBoxLayout * layout = new QVBoxLayout();
                layout->addWidget(m_scrollArea);
                setLayout(layout);

                setWindowTitle(filename);
                resize(500, 400);

                // open file

                m_image = QImage(filename);
                if (m_image.isNull()) {
                QMessageBox::information(this, tr("Warning"),
                tr("Cannot load %1.").arg(filename));
                return;
                }

                m_imageLabel->setPixmap(QPixmap::fromImage(m_image));

                m_scaleFactor = 1.0;
                normalSize();

                m_pixelatorFlag = false;

                //connect(parent->ui.actionPixelator, SIGNAL(triggered()), this, SLOT(pixelatorOn()));

                m_difference = 20;
                m_currentColor = Qt::black;
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::zoomIn()
                {

                scaleImage(1.25);
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::zoomOut()
                {
                scaleImage(0.8);
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::normalSize()
                {
                m_imageLabel->adjustSize();
                m_scaleFactor = 1.0;
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::fitToWindow( bool fitToWindow )
                {
                m_scrollArea->setWidgetResizable(fitToWindow);
                if (!fitToWindow) {
                normalSize();
                }
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::scaleImage( double factor )
                {
                Q_ASSERT(m_imageLabel->pixmap());
                m_scaleFactor *= factor;
                m_imageLabel->resize(m_scaleFactor * m_imageLabel->pixmap()->size());

                adjustScrollBar(m_scrollArea->horizontalScrollBar(), factor);
                adjustScrollBar(m_scrollArea->verticalScrollBar(), factor);
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::adjustScrollBar( QScrollBar *scrollBar, double factor )
                {
                scrollBar->setValue(int(factor * scrollBar->value()

                • ((factor - 1) * scrollBar->pageStep()/2)));
                  }
                  //-----------------------------------------------------------------------------
                  void ImageWidget::mousePressEvent( QMouseEvent * event )
                  {
                  QPointF pos = m_imageLabel->mapFromParent(event->pos());

                double x = pos.x();
                double y = pos.y();

                // Calculate scale and image sizes
                double h = m_imageLabel->height();
                double w = m_imageLabel->width();

                if(x>w || y>h)
                return;

                if(h>size().height() || w>size().width())
                {
                m_scaleFactor = 1.0;
                }

                x *= m_scaleFactor;
                y *= m_scaleFactor;

                pos = QPointF(x,y);

                QRgb pixel = m_image.pixel(x,y);

                m_currentColor = QColor::fromRgb(pixel);

                emit colorSelected(m_currentColor.name(),x,y);

                switch (m_action)
                {
                case ePixel:
                proccessImage(m_currentColor,false);
                break;
                case eErase:
                eraseImage(pos, QPointF(pos.x()+50,pos.y()+50));
                break;
                case eNoact:
                break;
                }
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::keyPressEvent( QKeyEvent * event )
                {
                switch(event->key())
                {
                case Qt::Key_Z:
                {
                if(event->modifiers() == Qt::ControlModifier)
                revertChanges();
                }
                break;
                default:
                QWidget::keyPressEvent(event);
                }
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::proccessImage(QColor color, bool inverse)
                {
                // Search algorithm

                QImage image = m_image;

                for(int y = 0; y < image.height(); y++)
                {
                for(int x = 0; x < image.width(); x++)
                {
                QRgb currentPixel = image.pixel(x,y);

                if( qAbs(qRed(currentPixel) - color.red()) > m_difference &&
                qAbs(qGreen(currentPixel) - color.green()) > m_difference &&
                qAbs(qBlue(currentPixel) - color.blue()) > m_difference)
                {
                if(!inverse)
                image.setPixel(x,y,qRgb(255,255,255));
                }
                else
                {
                if(inverse)
                image.setPixel(x,y,qRgb(255,255,255));
                }
                }
                }
                m_imageLabel->setPixmap(QPixmap::fromImage(image));

                // QMessageBox::information(this, tr("Done"),
                // tr("Processing image done.n"
                // "The document has been modified."),
                // QMessageBox::Ok);
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::eraseImage( const QPointF & startPoint,const QPointF & endPoint )
                {
                QImage image = m_image;

                for(int y = 0; y < image.height(); y++)
                for(int x = 0; x < image.width(); x++)
                if(y > startPoint.y() && y < endPoint.y())
                if(x > startPoint.x() && x<endPoint.x())
                image.setPixel(x,y,qRgb(255,255,255));

                m_imageLabel->setPixmap(QPixmap::fromImage(image));

                m_image = image;
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::revertChanges()
                {
                QImage image = m_imageLabel->pixmap()->toImage();

                m_imageLabel->setPixmap(QPixmap::fromImage(m_image));

                m_image = image;
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::onChangeDifference(int difference)
                {
                m_difference = difference;
                //proccessImage(m_currentColor,false);
                }
                //-----------------------------------------------------------------------------
                void ImageWidget::setCurrentAction( curAction action )
                {
                m_action = action;
                }
                //-----------------------------------------------------------------------------
                @

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Anticross
                  wrote on last edited by
                  #9

                  I done this:
                  make m_scalefactor double;
                  When zoom in 0,8;
                  when zoom out 1,25;

                  if(h>size().height() || w>size().width())
                  {
                  m_scaleFactor = 1.0;
                  }

                  But I still have wrong coords in mouse press event x and y if I already make zomming, without zumming it's work correct. Please check somebody my code and make some corrections or recommendations.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mahdhaoui
                    wrote on last edited by
                    #10

                    Hello, i'am Novice in Qt program. I'am interested for you program (extention of imageViewer).
                    Can you post it if you have the solution. Thank you.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      Anticross
                      wrote on last edited by
                      #11

                      I post header and source file of my Image widget class before. So you can see it, mahdhaoui. You just need to make an empty qt solution and use my class :)

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved