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. Displaying QImage on another QImage?
QtWS25 Last Chance

Displaying QImage on another QImage?

Scheduled Pinned Locked Moved General and Desktop
12 Posts 3 Posters 5.2k 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.
  • Z Offline
    Z Offline
    ZeeQ
    wrote on last edited by
    #1

    Hi all,

    i am making an application which looks like as below.
    !http://img198.imageshack.us/img198/817/screenshot1yi.png(Image)!
    i am taking a matrix and converting it to QpixMap and adding it to Qgraphicsscene. Now this map is changed after every 4 sec and i call update after every 4 sec and it updates this image. at this level it works perfectly fine. Now i want to add more information on that image. for example in image the white line which shows the path of robot. i am doing it on same image. The problem is that robot path is updated very frequently means after 1/2 second but drawing is done after 4 sec.
    So is there any way of updating this path in high frequency. secondly is it possible that i use something else for displaying this white line.
    @void MainWindow::paintEvent(QPaintEvent *e)
    {

    my_mutex.lock();
    //this part updates the red lines and black background
    for(unsigned int y = 0; y < 4000; y++) {
    for(unsigned int x = 0; x < 4000; x++) {
    unsigned int i = x + (4000 - y - 1) * 4000;
    if (data12[i] == 0)
    {

    image->setPixel(x,y,1);
    }
    else if (data12[i] == 100)
    {
    //cout<<"i can see this"<<endl;
    image->setPixel(x,y,3);
    }
    else {
    image->setPixel(x,y,1);
    }
    }
    }
    testvar=false;
    my_mutex.unlock();
    //this part updates the white lines on same image
    for(int i=0; i< pose_x.size(); i++)
    {
    //cout << "i am in pose drawing "<<endl;
    image->setPixel(pose_x.at(i),pose_y.at(i),2);
    }
    image->setPixel(pose_x.back(),pose_y.back(),4);

    *pixmap= QPixmap::fromImage(*image);
    scene->addPixmap(*pixmap);

    }@

    Thanks in advance.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      DerManu
      wrote on last edited by
      #2

      Save the vector information of the white line and redraw it ontop of the image in a QPixmap? Or just buffer the white line in a separate QPixmap and just blit the background and the foreground faster than the background buffer is actually updated.

      Further, I stick with my recommendations from "last time":http://qt-project.org/forums/viewthread/17566/.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        The code you post triggers a WTF or two when I read it...

        The issues start at line 4. What is that mutex doing there? You're not trying to redraw from multiple threads, are you? That is not supported and will get you into trouble.

        Lines 6 and 7 is where the horror already pointed out by DerManu starts. Really? Iterating point-by-point through a 4000x4000 matrix for painting? Every time an update takes place? You cannot be serious. It is worse enough you do it at all, but doing it every paint is redicule. Just do it when anything has changed. Render into a pixmap and keep that pixmap around for the next paintEvent. Or, better yet, see if you can distill lines from the pixels (once, of course...) and draw these as items in your scene. That will hugely improve your performance.

        Then, why are you not really taking advantage of the QGraphicsView? If you want to put multiple objects on top of each other, just create separate items for them (in this case: your walls and your path) and update each of them as needed. No need to render them into the same item. That way, you can take advantage of QGrahpicsViews buffering optimizations.

        At the last line, you are adding items to the scene in the paintEvent. Don't. You're changing the item while painting, triggering another paint, etcetera. Further more, you're adding item after item in the view, each one a bitmap of 16MP weighing in about 64MB. You're going to run out of memory fast, even on a multi-GB machine. Who is cleaning up the older items?

        recommendations
        To summarize my recommendations:

        • Throw away the MainWindow::paintEvent reimplementation.
        • Create two custom -QGraphicsViewItem- QGraphicsItem derived items, one to represent your walls, one for your robot path and add an instance of each to the scene once.
        • Update these items when needed: when new data actually comes in. Cache any expensive rendering of underlying data structures inside them so they can paint themselves quickly.
        • See if you can optimize the rendering of your items by making them into lines instead of big bitmaps. Should be easy for your robot's path, I think.
        1 Reply Last reply
        0
        • Z Offline
          Z Offline
          ZeeQ
          wrote on last edited by
          #4

          ok i got it. Regarding the mutex i am not updating it in someother thread but i am getting these pixels values from ROS and saving them in a vector thats why i am using it.

          For updating all pixels now i do it for only change pixels. but i am not sure how i am suppose to do distill lines from pixels as you suggested.

          now i am cleaning the scene and pixmap before adding the new one in it like this
          @scene->clear();
          QPixmapCache::clear();
          *pixmap= QPixmap::fromImage(*image);
          scene->addPixmap(*pixmap);@

          but still the application causes to slow the system.

          From your recommendations what do you mean by QGraphicsViewItem ? i have QImage for walls and i can have QImage for path can these be represented as Item ?

          Thanks

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            The actual distilling of the lines would be an image processing task, and is outside of the scope of Qt.

            You are really not listening to the suggestions. Why do you clear the scene and the pixmap cache? And from where do you do that?

            You only need to update the item representing the walls or the path if and when needed. There is no need to rebuild the entire scene.

            I meant [[doc:QGraphicsItem]], not QGraphicsViewItem. Sorry for that confusion. Such an item can be (derived from) a QGraphicsPixmapItem, but it might also be another type. You really should look if you can't at least get the robot path in a different format than a huge bitmap. That seems like a really awkward, inefficient and inflexible representation to me.

            1 Reply Last reply
            0
            • Z Offline
              Z Offline
              ZeeQ
              wrote on last edited by
              #6

              @Andre Thanks for being patient with newbies. I follow your suggestions but have one problem. After making Walls and Path independent QGraphicsItem. when i call update in both independently why it generates call to paint of the both class and both paint updates themselves.

              Thanks

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                Sorry, I don't understatement the problem. Sure the paint event of both items is called when needed. Why is that a problem?

                1 Reply Last reply
                0
                • Z Offline
                  Z Offline
                  ZeeQ
                  wrote on last edited by
                  #8

                  I am calling update in both items independently with different frequency depending on the data arrived. Now the path data arrives with very high frequency like once in half second so i call update on it but it also causes map paint to be called since its frequency is once in a 4 second.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    Of course. If you change the path, the underlying item (the map) needs to be repainted too. After all: they may overlap.

                    You'll just have to make sure the actual paint is fast enough. Did you reimplement that yet by iterating over your huge matrix only when new data comes in?

                    1 Reply Last reply
                    0
                    • Z Offline
                      Z Offline
                      ZeeQ
                      wrote on last edited by
                      #10

                      it is not slowing the system any more but was just wondering about the behaviour of paint.

                      i am still iterating through the full matrix but i am changing only those pixels which value is change. I am still not sure how to deal with this efficiently.
                      i am getting this 4000 * 4000 matrix in other software so cant do anything about it. Thanks alot.

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        andre
                        wrote on last edited by
                        #11

                        As I said before: the trick is to not iterate over the matrix every time you have to paint, but only do that when the data is changed. You can store the result of your iteration in a pixmap, and paint that pixmap in the paintEvent(). That should speed up your application a lot.

                        1 Reply Last reply
                        0
                        • Z Offline
                          Z Offline
                          ZeeQ
                          wrote on last edited by
                          #12

                          Hi Andre;
                          i am back with another problem not sure to start new thread but as i explained my work here more so continuing from here will be more appropriate.
                          So actual question is "At the end point of path i want to put an image of robot for which i made some 8x8 pixels image now i have to rotate that image to show the direction of robot whenever it is changed in other system(ROS)."
                          Now after using the traditional way found on blogs and qt documentation i got one problem the size of image (8x8) increases whenever i rotate other than 90 degree angle . which is very strange for me.
                          i am doing it in following way.
                          @
                          QTransform robot_transform;
                          QImage *robot;
                          robot_transform.rotate(angle);
                          *robot = robot->transformed(robot_transform);@

                          and after that in paint function i paint it.

                          @painter->drawImage(pose_x.back(),pose_y.back(),*robot);@

                          Thanks in advance

                          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