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. Issue when rotating an QImage
Forum Updated to NodeBB v4.3 + New Features

Issue when rotating an QImage

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 2.4k Views 2 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.
  • S Offline
    S Offline
    sylorr
    wrote on 19 Dec 2018, 22:56 last edited by sylorr
    #1

    Hi all, I have trouble when rotating an image.

    To achieve that, I firstly try out QPixmap + QImage. And use a QMatrix to do the rotation:

    // myImage.png is a squared picture (same w and h)
    QImage image(":/resources/myImage.png")
    QMatrix rotate_matrix;
    QPoint center = image.rect().center();
    
    // this line seems to have no effect on the result
    rotate_matrix.translate(center.x(), center.y());
    
    rotate_matrix.rotate(degree);
    QImage dstImage = image.transformed(rotate_matrix);
    QPixmap pic = QPixmap::fromImage(dstImage);
    
    // "this" is a QLabel
    this->setPixmap(pic);
    

    However, I found that the rotating is not working as I expected. It seems that the image is "floating" a bit. It should be rotating around its center (pivot point). The truth is it rotates around a little bit offsets to the center, which makes the image "move" a bit when rotating.

    And then I try to draw an image with QPainter. To be honest, this method is a bit complicated because I have to calculate the center's offset every time I do (cause I have to rotate around coordinate (0,0) instead of image's center, and I need to recalculate the image's center's position)

    painter.rotate(degree);
    

    I am 99% sure that my offset calculation is correct. But the rotation is still incorrect (with some offsets)

    Could someone help me out? Do I rotate the image in the wrong way?

    Note: platform: Ubuntu 16.04 + Qt5.6 + C++14

    K 1 Reply Last reply 20 Dec 2018, 00:32
    0
    • S sylorr
      19 Dec 2018, 22:56

      Hi all, I have trouble when rotating an image.

      To achieve that, I firstly try out QPixmap + QImage. And use a QMatrix to do the rotation:

      // myImage.png is a squared picture (same w and h)
      QImage image(":/resources/myImage.png")
      QMatrix rotate_matrix;
      QPoint center = image.rect().center();
      
      // this line seems to have no effect on the result
      rotate_matrix.translate(center.x(), center.y());
      
      rotate_matrix.rotate(degree);
      QImage dstImage = image.transformed(rotate_matrix);
      QPixmap pic = QPixmap::fromImage(dstImage);
      
      // "this" is a QLabel
      this->setPixmap(pic);
      

      However, I found that the rotating is not working as I expected. It seems that the image is "floating" a bit. It should be rotating around its center (pivot point). The truth is it rotates around a little bit offsets to the center, which makes the image "move" a bit when rotating.

      And then I try to draw an image with QPainter. To be honest, this method is a bit complicated because I have to calculate the center's offset every time I do (cause I have to rotate around coordinate (0,0) instead of image's center, and I need to recalculate the image's center's position)

      painter.rotate(degree);
      

      I am 99% sure that my offset calculation is correct. But the rotation is still incorrect (with some offsets)

      Could someone help me out? Do I rotate the image in the wrong way?

      Note: platform: Ubuntu 16.04 + Qt5.6 + C++14

      K Offline
      K Offline
      kenchan
      wrote on 20 Dec 2018, 00:32 last edited by
      #2

      @sylorr
      I think you are supposed to translate the centre of the image back to the origin not offset it to the centre.
      So I am guessing your initial translation should be the inverse of what it is now.
      NOTE: I only reasoned this and did not test it.

      1 Reply Last reply
      1
      • S Offline
        S Offline
        sylorr
        wrote on 20 Dec 2018, 00:50 last edited by
        #3

        @kenchan
        Thanks for the response. But I have tested it out. It's not the issue.

        Now I have tackled down the issue to avoid image "floating" by using QPainter::drawImage() to draw a rotated QImage on my widget. However, I found another issue that once I rotate something by

        QMatrix::rotate(degree);
        

        The QImage scaled automatically for me. I would update the rotating degree every 0.1 seconds and my image just keeps scaling back and forth. The larger (in abs()) degree it rotates, the smaller the image it is. I really wonder how this rotate function is implemented.

        K K 2 Replies Last reply 20 Dec 2018, 01:31
        0
        • S sylorr
          20 Dec 2018, 00:50

          @kenchan
          Thanks for the response. But I have tested it out. It's not the issue.

          Now I have tackled down the issue to avoid image "floating" by using QPainter::drawImage() to draw a rotated QImage on my widget. However, I found another issue that once I rotate something by

          QMatrix::rotate(degree);
          

          The QImage scaled automatically for me. I would update the rotating degree every 0.1 seconds and my image just keeps scaling back and forth. The larger (in abs()) degree it rotates, the smaller the image it is. I really wonder how this rotate function is implemented.

          K Offline
          K Offline
          kenchan
          wrote on 20 Dec 2018, 01:31 last edited by
          #4

          @sylorr

          from the docs for QImage::transformed

          QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode = Qt::FastTransformation) const
          Returns a copy of the image that is transformed using the given transformation matrix and transformation mode.
          The transformation matrix is internally adjusted to compensate for unwanted translation; i.e. the image produced is the smallest image that contains all the transformed points of the original image. Use the trueMatrix() function to retrieve the actual matrix used for transforming an image.
          Unlike the other overload, this function can be used to perform perspective transformations on images.
          See also trueMatrix() and Image Transformations.
          

          So that kind of makes sense.

          S 1 Reply Last reply 20 Dec 2018, 03:02
          0
          • S sylorr
            20 Dec 2018, 00:50

            @kenchan
            Thanks for the response. But I have tested it out. It's not the issue.

            Now I have tackled down the issue to avoid image "floating" by using QPainter::drawImage() to draw a rotated QImage on my widget. However, I found another issue that once I rotate something by

            QMatrix::rotate(degree);
            

            The QImage scaled automatically for me. I would update the rotating degree every 0.1 seconds and my image just keeps scaling back and forth. The larger (in abs()) degree it rotates, the smaller the image it is. I really wonder how this rotate function is implemented.

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 20 Dec 2018, 01:54 last edited by
            #5

            @sylorr said in Issue when rotating an QImage:

            As @kenchan wrote, you should move the origin of the coordinate system back after rotating.

            The QImage scaled automatically for me. I would update the rotating degree every 0.1 seconds and my image just keeps scaling back and forth. The larger (in abs()) degree it rotates, the smaller the image it is. I really wonder how this rotate function is implemented.

            It may depend on how you move that rotating degree, numerical errors apply here.

            Also rotating something to anything but 0, 90, -90, 180 degrees is lossy. In that case pixels do not fit in their original positions, so you may see some "change" which would be more pronounced for small images.

            Lastly, the transformation is implemented the conventional way - through an extended-space transformation matrix which is applied to the pixel's coordinates (i.e the points) and then the space-extension is projected-out (i.e. clipped to 2D).
            I'm not sure what kind of interpolation is used, but I don't imagine it to be one that's very high quality or that's heavy to compute, for obvious reasons.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • K kenchan
              20 Dec 2018, 01:31

              @sylorr

              from the docs for QImage::transformed

              QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode = Qt::FastTransformation) const
              Returns a copy of the image that is transformed using the given transformation matrix and transformation mode.
              The transformation matrix is internally adjusted to compensate for unwanted translation; i.e. the image produced is the smallest image that contains all the transformed points of the original image. Use the trueMatrix() function to retrieve the actual matrix used for transforming an image.
              Unlike the other overload, this function can be used to perform perspective transformations on images.
              See also trueMatrix() and Image Transformations.
              

              So that kind of makes sense.

              S Offline
              S Offline
              sylorr
              wrote on 20 Dec 2018, 03:02 last edited by sylorr
              #6

              @kenchan
              Thanks! I have checked and tested that trueMatrix() function, the issue still exists. But that reminds me another truth that may cause the problem.

              So my QWidget is set to be sizing 100*100, and when I draw the image with QPainter::drawImage(rect, image), i need to pass a rect (in my case I just pass QRect(0, 0, 100, 100) everytime because this is my QWidget's rect()).

              However, an image is squared, which means when it rotates, taking an example of left-top corner (0, 0), may become negative. And in order to draw all the image, I guess Qt may scale it within the function QPainter::drawImage() to fit into that small QRect.

              For sure that is just a guess, but it totally makes sense in the case here.

              1 Reply Last reply
              0

              1/6

              19 Dec 2018, 22:56

              • Login

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