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. Qpainter scale pixmap to parent with aspect ratio

Qpainter scale pixmap to parent with aspect ratio

Scheduled Pinned Locked Moved Unsolved General and Desktop
qpainterscale to fitaspect ratiopixm
15 Posts 4 Posters 12.8k Views
  • 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.
  • raven-worxR raven-worx

    @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

    I tried your code but the image "plopps" strangely and gets bigger than the frame for a short time...

    as stated its untested, and straight out of my head. But i guess i'ts just a minor mistake in the calculation.

    Why caching the pixmap? Did you do this for performance reasons?

    yes, because there is no need to load a pixmap from file in every paintEvent() call!

    pauleddP Offline
    pauleddP Offline
    pauledd
    wrote on last edited by
    #6

    @raven-worx said in Qpainter scale pixmap to parent with aspect ratio:

    yes, because there is no need to load a pixmap from file in every paintEvent() call!

    Okay but later I will use this:

    bool VideoFrame::startCam()
    {
    ...
    for(int i=0;i<img->height();i++)
        {
            memcpy(img->scanLine(i), frame1.row(i).data, img->bytesPerLine());
        }
        update();
    ...
    }
    ...
    
    
    
    void VideoFrame::paintEvent(QPaintEvent *)
    {
    ...
        const QPixmap paintPixmap(QPixmap::fromImage(*img));
    ...
    }
    

    I have camera data from frame1 that is constantly copied to "img" and then drawed in the paintEvent... would that caching make then sense too? I used the static image just as placeholder to demonstrate...

    @VRonin
    I got a new problem with your code.. how can I then rotate the rect/image around its centerpoint. If I simply rotate the painter the centerpoint lays in the upper left corner. I then tried to translate the painter to half of the image dimensions and then tried painter.rotate but with your code that doesnt work anymore, can you give me a hint how to solve that?

    raven-worxR VRoninV 2 Replies Last reply
    0
    • pauleddP pauledd

      @raven-worx said in Qpainter scale pixmap to parent with aspect ratio:

      yes, because there is no need to load a pixmap from file in every paintEvent() call!

      Okay but later I will use this:

      bool VideoFrame::startCam()
      {
      ...
      for(int i=0;i<img->height();i++)
          {
              memcpy(img->scanLine(i), frame1.row(i).data, img->bytesPerLine());
          }
          update();
      ...
      }
      ...
      
      
      
      void VideoFrame::paintEvent(QPaintEvent *)
      {
      ...
          const QPixmap paintPixmap(QPixmap::fromImage(*img));
      ...
      }
      

      I have camera data from frame1 that is constantly copied to "img" and then drawed in the paintEvent... would that caching make then sense too? I used the static image just as placeholder to demonstrate...

      @VRonin
      I got a new problem with your code.. how can I then rotate the rect/image around its centerpoint. If I simply rotate the painter the centerpoint lays in the upper left corner. I then tried to translate the painter to half of the image dimensions and then tried painter.rotate but with your code that doesnt work anymore, can you give me a hint how to solve that?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #7

      @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

      I have camera data from frame1 that is constantly copied to "img" and then drawed in the paintEvent... would that caching make then sense too?

      basically yes, since you do not know how often the paintEvent() will be called until the next image is received.

      And also btw, it's not necessary to convert the QImage to a QPixmap just for drawing. QPainter also provides methods to draw a QImage directly.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      1
      • pauleddP pauledd

        @raven-worx said in Qpainter scale pixmap to parent with aspect ratio:

        yes, because there is no need to load a pixmap from file in every paintEvent() call!

        Okay but later I will use this:

        bool VideoFrame::startCam()
        {
        ...
        for(int i=0;i<img->height();i++)
            {
                memcpy(img->scanLine(i), frame1.row(i).data, img->bytesPerLine());
            }
            update();
        ...
        }
        ...
        
        
        
        void VideoFrame::paintEvent(QPaintEvent *)
        {
        ...
            const QPixmap paintPixmap(QPixmap::fromImage(*img));
        ...
        }
        

        I have camera data from frame1 that is constantly copied to "img" and then drawed in the paintEvent... would that caching make then sense too? I used the static image just as placeholder to demonstrate...

        @VRonin
        I got a new problem with your code.. how can I then rotate the rect/image around its centerpoint. If I simply rotate the painter the centerpoint lays in the upper left corner. I then tried to translate the painter to half of the image dimensions and then tried painter.rotate but with your code that doesnt work anymore, can you give me a hint how to solve that?

        VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #8

        @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

        how can I then rotate the rect/image around its centerpoint.

        Do not rotate the painter, rotate the pixmap.

        QPainter painter(this);
            QSize widgetSize = rect().size();
            QPixmap paintPixmap(QStringLiteral("image_320.png"));
            QTransform rotateTransform;
            rotateTransform.rotate(45);
            paintPixmap=paintPixmap.transformed(rotateTransform);
            const auto newHeight = widgetSize.width()*paintPixmap.height()/paintPixmap.width();
            if(newHeight<=widgetSize.height())
                widgetSize.setHeight(newHeight);
            else
                widgetSize.setWidth(widgetSize.height()*paintPixmap.width()/paintPixmap.height());
            style()->drawItemPixmap(&painter,rect(),Qt::AlignCenter,paintPixmap.scaled(widgetSize));
        

        Caching does makes a lot of sense, you can use QPixmapCache

        @raven-worx said in Qpainter scale pixmap to parent with aspect ratio:

        QPainter also provides methods to draw a QImage directly.

        Yes but:

        • it just calls QPixmap::fromImage internally: https://code.woboq.org/qt5/qtbase/src/gui/painting/qpaintengine.cpp.html#625
        • QStyle doesn't have it

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        3
        • pauleddP Offline
          pauleddP Offline
          pauledd
          wrote on last edited by
          #9

          Great, thank you both for the hints, I will try to go on by myself but keep that topic unresolved for a few days as long as I am not finshed.

          1 Reply Last reply
          0
          • pauleddP Offline
            pauleddP Offline
            pauledd
            wrote on last edited by
            #10

            @VRonin I dont yet get behind the way you draw the pixmap in your code.
            you use (still noob beginner ;) ):

            style()->drawItemPixmap(&painter,rect(),Qt::AlignCenter,paintPixmap.scaled(widgetSize));
            

            I've never seen such a style()-> ... alone without an object... it seems to be not declared somewhere, to what does it refer to? To the Qpainter?

            The same is with the:

            QSize widgetSize = rect().size();
            

            rect().size(); refers to the QFrame? I usually would expext an "this.rect().size();"

            And that brings me to another question. If I need to draw an ellipse, as I did
            previously with painter.drawEllipse, into that image area, for example at position 40,40 seen from top/left and staying at that point while rotating with the image how would that fit into your way to draw with:

            style()->drawItem...
            

            or is that not possible?

            mrjjM VRoninV 2 Replies Last reply
            0
            • pauleddP pauledd

              @VRonin I dont yet get behind the way you draw the pixmap in your code.
              you use (still noob beginner ;) ):

              style()->drawItemPixmap(&painter,rect(),Qt::AlignCenter,paintPixmap.scaled(widgetSize));
              

              I've never seen such a style()-> ... alone without an object... it seems to be not declared somewhere, to what does it refer to? To the Qpainter?

              The same is with the:

              QSize widgetSize = rect().size();
              

              rect().size(); refers to the QFrame? I usually would expext an "this.rect().size();"

              And that brings me to another question. If I need to draw an ellipse, as I did
              previously with painter.drawEllipse, into that image area, for example at position 40,40 seen from top/left and staying at that point while rotating with the image how would that fit into your way to draw with:

              style()->drawItem...
              

              or is that not possible?

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #11

              Hi
              style()
              refers to the QWidget member method that returns the active
              QStyle.
              It would be the same as this->Style().
              Same with
              rect().size();
              also means this-> rect().size();
              They are defined in the base class. ( QWidget )

              1 Reply Last reply
              1
              • pauleddP pauledd

                @VRonin I dont yet get behind the way you draw the pixmap in your code.
                you use (still noob beginner ;) ):

                style()->drawItemPixmap(&painter,rect(),Qt::AlignCenter,paintPixmap.scaled(widgetSize));
                

                I've never seen such a style()-> ... alone without an object... it seems to be not declared somewhere, to what does it refer to? To the Qpainter?

                The same is with the:

                QSize widgetSize = rect().size();
                

                rect().size(); refers to the QFrame? I usually would expext an "this.rect().size();"

                And that brings me to another question. If I need to draw an ellipse, as I did
                previously with painter.drawEllipse, into that image area, for example at position 40,40 seen from top/left and staying at that point while rotating with the image how would that fit into your way to draw with:

                style()->drawItem...
                

                or is that not possible?

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #12

                @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

                I usually would expext an "this.rect().size();"

                Do you come from python? it is this->rect() and this->style() but in C++ you don't need to explicitly use this in front.

                to what does it refer to? To the Qpainter?

                http://doc.qt.io/qt-5/qwidget.html#style

                @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

                If I need to draw an ellipse, as I did

                QStyle/QStylePainter is an abstraction over the drawing of controls, it does not provide drawing of basics like lines and circles. See http://doc.qt.io/qt-5/qstyle.html#developing-style-aware-custom-widgets

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • pauleddP Offline
                  pauleddP Offline
                  pauledd
                  wrote on last edited by
                  #13

                  Okay thanks, so I will paint an ellipse as png and then load it the same way you did with the "style()->drawItem..." :)

                  VRoninV 1 Reply Last reply
                  0
                  • pauleddP pauledd

                    Okay thanks, so I will paint an ellipse as png and then load it the same way you did with the "style()->drawItem..." :)

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #14

                    @pauledd said in Qpainter scale pixmap to parent with aspect ratio:

                    I will paint an ellipse as png

                    Saving and loading to png file format is expensive, I would advise against it.

                    If the position of the ellipsis doesn't change in the pixmap then draw it using QPainter on the pixmap and cache it. If the ellipsis is dynamic then paint it directly on the widget from the paintEvent

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    0
                    • pauleddP Offline
                      pauleddP Offline
                      pauledd
                      wrote on last edited by
                      #15

                      Ok, I will try that...
                      Maybe I should have been more clearly what I intend to get...
                      I had it all working already, just without the scaling issue

                      alt text

                      I get camera images and I let opencv compute min/max values and a centerpoint. Somethimes the camera is rotated in a undesired position so the user should be able to rotate the view, including the measurepoints, and more complex including the point values so that the stay at the points but do not rotate staying readable...

                      I keep trying with qpainter draw

                      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