Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

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

    General and Desktop
    3
    11
    15293
    Loading More Posts
    • 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.
    • A
      Anticross last edited by

      I have an MDI Application. Each child window is QWidget based class. This class(ImageWidget class) contains scroll area and QLabel in this area. In Qlabel we have image (like in Qt examples Image viewer) and I have zoomIn and zoomOut, normalSize functions there. So I add a function to process the image, and need actually know coordinates of image selected pixel by cursor coordinates:
      @void ImageWidget::mousePressEvent( QMouseEvent * event )
      {
      int x = event->pos().x();
      int y = event->pos().y();

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

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

      x = x/m_scaleFactor;
      y = y/m_scaleFactor;

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

      QColor color = QColor::fromRgb(pixel);

      }@
      So if my image is zoomed out I can get right coordinates by dividing current coordinates(each of it x and y) to scale factor. But if image is zoomed in and it's new size more then size of widgets this method don't work and I get wrong coordinates. what can I do now ?

      1 Reply Last reply Reply Quote 0
      • G
        giesbert last edited by

        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 Reply Quote 0
        • A
          Anticross last edited by

          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 Reply Quote 0
          • A
            Anticross last edited by

            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 Reply Quote 0
            • G
              giesbert last edited by

              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 Reply Quote 0
              • A
                Anticross last edited by

                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 Reply Quote 0
                • A
                  Anticross last edited by

                  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 Reply Quote 0
                  • A
                    Anticross last edited by

                    *.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 Reply Quote 0
                    • A
                      Anticross last edited by

                      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 Reply Quote 0
                      • M
                        mahdhaoui last edited by

                        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 Reply Quote 0
                        • A
                          Anticross last edited by

                          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 Reply Quote 0
                          • First post
                            Last post