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. Image rotation causes distortion
Forum Updated to NodeBB v4.3 + New Features

Image rotation causes distortion

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 5.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.
  • Q Offline
    Q Offline
    qtBeginner
    wrote on last edited by
    #1

    Hi

    I making some image to rotate each 10 degrees. Rotation itself works fine. My problem is related to image. After some iterations image gets distorted. This occurs with any degree value.
    My guess is because image bounding box. If so, is there a way to maintain proportions?

    Original Image:
    !http://imageshack.us/a/img268/6365/ship1p.png(Original image)!

    Distorted Image:
    !http://imageshack.us/a/img266/8501/ship2.png(Distorted Image)!

    This is my code:
    @
    void Ship::Move(int x, int y)
    {
    QPixmap rotatePixmap(shipPixels.size());
    rotatePixmap.fill(Qt::transparent);

    QPainter p(&rotatePixmap);
    p.translate(rotatePixmap.size().width() / 2, rotatePixmap.size().height() / 2);
    p.rotate(degree);
    p.translate(-rotatePixmap.size().width() / 2, -rotatePixmap.size().height() / 2);
    
    p.drawPixmap(0, 0, shipPixels);
    p.end();
    
    shipPixels = rotatePixmap;
    this->setPixmap(shipPixels);
    this->move(QPoint(x, y));
    degree = 0;
    

    }
    @

    Thanks for replies.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      I would assume it is because you are accumulating errors with every rotation. You rotate the image and replace the original (line 14), then rotate that rotated image, then rotate that image etc. Rotation maths is precise but pixels are in discrete locations so each rotation introduces more error.

      You should start from the same, unrotated image and rotate it once by the cumulative amount of rotation desired. If the increments are fixed then you should probably also do this once only and cache the 36 (or whatever) images.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        MuldeR
        wrote on last edited by
        #3

        Did you play around with the flags that can be set via QPainter::setRenderHint() ????

        Those look related:

        • QPainter::Antialiasing
        • QPainter::SmoothPixmapTransform
        • QPainter::HighQualityAntialiasing

        My OpenSource software at: http://muldersoft.com/

        Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

        Go visit the coop: http://youtu.be/Jay...

        1 Reply Last reply
        0
        • Q Offline
          Q Offline
          qtBeginner
          wrote on last edited by
          #4

          Mulder I tried these hints before. They just smooth the error.
          ChrisW67, based on your comment, if I do this I'll continue to accumulate the error eve if I unrotate the image. For me Qt did the translation and preserves the image quality

          1 Reply Last reply
          0
          • M Offline
            M Offline
            MuldeR
            wrote on last edited by
            #5

            Well, bitmap (pixel-based) images have a limited resolution by nature. You can't rotate such an image in an "exact" way, except for rotating by multiples of 90°. For other rotations degrees the output has to be interpolated. What you call "distorted" looks like a "nearest neighbor" sampling. Using a "bilinear" or "bicubic" transform will create a more "smooth" result. This usually is much preferred for "natural" images. It may not look that great for a "synthetic" image like yours. Keep in mind that your original image already looks rather "pixelated"...

            (I think for what you are doing it might be the better solution to work with vector-based graphics, not bitmaps)

            My OpenSource software at: http://muldersoft.com/

            Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

            Go visit the coop: http://youtu.be/Jay...

            1 Reply Last reply
            0
            • C Offline
              C Offline
              ChrisW67
              wrote on last edited by
              #6

              [quote author="qtBeginner" date="1349895757"]
              ChrisW67, based on your comment, if I do this I'll continue to accumulate the error ever if I unrotate the image.[/quote]
              I didn't say unrotate then re-rotate. I said start with the same, original, unrotated image every time.

              See the difference between the two in this example:
              @
              #include <QtGui>
              #include <QDebug>

              int main(int argc, char *argv[])
              {
              QApplication app(argc, argv);
              QPainter p;

              // Original image
              QPixmap original("ship1p.png");
              
              // Original rotated once to 30 degrees
              QPixmap test1(original.size());
              test1.fill(Qt::transparent);
              p.begin(&test1);
              p.translate(original.width() / 2, original.height() / 2);
              p.rotate(30);
              p.translate(-original.width() / 2, -original.height() / 2);
              p.drawPixmap(0, 0, original);
              p.end();
              
              test1.save("test1.png");
              
              // Original rotated to 30 degrees in 5 degree steps
              QPixmap test2(original);
              for (int i = 0; i < 6; ++i) {  // each loop accumulates errors
                  QPixmap temp(test2.size());
                  temp.fill(Qt::transparent);
                  p.begin(&temp);
                  p.translate(test2.width() / 2, test2.height() / 2);
                  p.rotate(5);
                  p.translate(-test2.width() / 2, -test2.height() / 2);
                  p.drawPixmap(0, 0, test2);
                  p.end();
                  test2 = temp;
              }
              test2.save("test2.png");
              
              return 0;
              

              }
              @

              Test1: One rotation
              !http://s16.postimage.org/9pft7dp7l/test1.png(Test1 One rotation)!
              Test 2: Accumulated rotations
              !http://s16.postimage.org/rtits0mw1/test2.png(Test2 Accumulated rotation)!

              So, track to total rotation the image requires and do a single rotation from a known good image rather than accumulate errors by continually rotating an image.

              MulderR's point about vector graphics is worth considering if it fits your requirements.

              1 Reply Last reply
              0
              • Q Offline
                Q Offline
                qtBeginner
                wrote on last edited by
                #7

                That's correct. My bad. I'll try your code right now.
                Thanks for both of you.

                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