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. How to Efficiently Draw a QImage to a Window.
QtWS25 Last Chance

How to Efficiently Draw a QImage to a Window.

Scheduled Pinned Locked Moved Unsolved General and Desktop
qimagedraw
19 Posts 3 Posters 13.6k 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.
  • as2388A Offline
    as2388A Offline
    as2388
    wrote on last edited by
    #3

    Size is 800x600. Kind is QImage, "loaded" with new QImage(800, 600, QImage::Format_ARGB32);. I'm drawing shapes/applying effects to them to synthesise video. All of these manipulations individually have little discernible impact on CPU utilisation except for drawing to the widget.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #4

      Ok, then since you are drawing anyway, why not draw directly on the widget ?

      On a side note, there's rarely need to allocate a QImage on the heap, why to you need to do it ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • as2388A Offline
        as2388A Offline
        as2388
        wrote on last edited by
        #5

        I don't understand what you mean by "draw directly" - I thought it was only possible to draw to widgets in paintEvent().

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #6

          Let me reformulate: since you are drawing your QImage on the widget, do you really need to pass by a QImage ? Can't you do the same drawing directly on the widget ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • as2388A Offline
            as2388A Offline
            as2388
            wrote on last edited by
            #7

            In my case I don't think so. But even if I could I don't see how that would help - the significant computational cost seems to be in getting paintEvent() to run in the first place, not initialising, manipulating or drawing QImages.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #8

              If you could that would mean you don't have to allocate a QImage each time you call paint event which in itself is already a gain.

              You should also rather work on a QPixmap since you're going to draw it, QPixmap is optimized for showing image on screen while QImage is optimized for IO and direct pixel access.

              What operations do you need to do exactly ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • as2388A Offline
                as2388A Offline
                as2388
                wrote on last edited by
                #9

                I think we're getting a little distracted trying to optimise the system instead of the drawing.

                Assuming that I could draw directly to a widget and therefore had no need for QImages or QPixmaps, I might be able to express that like this:

                MainWindow::MainWindow(QWidget *parent) :
                    QMainWindow(parent),
                    ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    QTimer *timer = new QTimer(this);
                    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
                    timer->start(50);
                }
                
                void MainWindow::paintEvent(QPaintEvent *event) {
                    QPainter painter(this);
                    painter.drawLine(QPointF(10, 10), QPointF(20, 20));
                    painter.end();
                }
                

                This uses 25% CPU, which seems like a lot just to draw a short line segment. How could this simple example be optimised (if at all)?

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  Is your application painting static content ? If so, then don't trigger update that much, there's no real need.

                  paintEvent will be called when needed so with your last sample, calling update every 50ms is useless and power consuming.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • as2388A Offline
                    as2388A Offline
                    as2388
                    wrote on last edited by
                    #11

                    Ok, so that may not have been a great example. In reality it will be dynamic content, so I really do need a frequent screen refresh. This is a slightly more representative example:

                    int x = 0;
                    void MainWindow::paintEvent(QPaintEvent *event) {
                        if (x > 500) x = 0;
                        QPainter painter(this);
                        painter.drawLine(QPointF(10, 10), QPointF(x++, x++));
                        painter.end();
                    }
                    
                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #12

                      Do you need some kind of graph ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • as2388A Offline
                        as2388A Offline
                        as2388
                        wrote on last edited by
                        #13

                        No, it's arbitrary shapes.

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #14

                          Is there some kind of history for these shapes are do you need to re-draw them all every time ?

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0
                          • as2388A Offline
                            as2388A Offline
                            as2388
                            wrote on last edited by
                            #15

                            Need to redraw.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #16

                              The first thing I'd do is optimize the data sent e.g. do you really need to build a line of 500 points if you already know the final coordinates ?

                              Otherwise, maybe consider using OpenGL

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              0
                              • as2388A Offline
                                as2388A Offline
                                as2388
                                wrote on last edited by
                                #17

                                So to confirm: there's no way to draw in Qt without invoking the relatively expensive update() first?

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #18

                                  Yes there is, do the drawing in another thread on a QImage and then trigger the update with that image. You have an example of this in the Mandelbrot example

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • SGaistS SGaist

                                    Yes there is, do the drawing in another thread on a QImage and then trigger the update with that image. You have an example of this in the Mandelbrot example

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #19

                                    @as2388

                                    Yes there is, do the drawing in another thread on a QImage and then trigger the update with that image.

                                    I'd add to @SGaist's great point - even convert the image to a QPixmap in the worker (after drawing it), and in the paint event just splat it onto the widget.

                                    Read and abide by the Qt Code of Conduct

                                    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