Results 1 to 10 of 10

Thread: Painting of lots of computationally heavy pixels

  1. #1
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Painting of lots of computationally heavy pixels

    Hello!

    I'm looking for techniques to speed up the painting of a lot of pixels, each of which requires up to a 1 millisecond to calculate. What I have so far is that I precalculate the colors of a 640x480 patch and then draw it pixel by pixel in paintEvent() using drawPoint(). The pure drawing takes several seconds, which is way too long. Is there something I can do to speed this up? Something like painting into an off screen pixmap and then showing that somehow?

    Soon I will have to be able to draw lines and curves on top of this 640x480 patch, which frequently change. How can I achieve that only the foreground is repainted and the patch stays in the background and doesn't need to be repainted at all?

    Thanks
    Cruz

  2. #2
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    1. You should create an in-Memory-image with your pixels! That can be drawn much faster. See QImage and QPixmap documentation.

    2. If you are calculating those values you will probably have some valueToColor function. Usually it is much faster to precalculate once a LUT (Look-Up-Table) with the required valueresolution.

    3. Describe what you want to do. It's hard to give good advice when you have to guess what its for.

    HIH

    Johannes

  3. #3
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    Thanks for your reply. Yes, I am already precalculating the look up table while I entertain the user with a progress bar. I'm looking into QPixmap as I'm writing this. So far I don't know how to show it on the screen but probably soon.

    What I want to do is drawing something like a heat map on the screen. The color of every pixel needs to be calculated individually. The calculated colors are in this look up table. So all I need is an efficient way to show the heat map. On top of the heat map I need to draw lines that outline the borders between cold and hot regions. These lines have a bias towards cold or hot and this bias is manually configurable. So whenever the user changes the bias, the lines have to be redrawn immidiately and it cannot take several seconds. So either I find a way to redraw the heat map and the lines in no time, or I have to figure out how not to redraw the heat map, only the lines.

  4. #4
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    1. Easiest way to show a pixmap inside a GUI is a QLabel. See QLabel::setPixmap;
    2. Rough layout would be:
    a) once on program-start or when user changes the heat-colors: Calculate your Colour-LUT. Usually a linear interpolation between several colors: black, red, yellow for instance.
    b) create the heatimage: create a QImage. iterate through every pixel. you could use scanline for most efficient memory access. calculate the heatvalue of this location. look the value up in the colour-lut. store the result in the image.
    c) displayimage: Copy-Construct from the heatimage. Use a QPainter on that copy to draw your regions. assign displayimage to your qlabel. label.setPixmap(QPixmap::fromImage(img)).

    This is going to be quite fast. But of course there are faster solutions. Like using a QGraphicsScene with OpenGL and have the heatimage stored as a texture. But I suggest you try the basic approach first.

    Need help with details?

    Johannes

  5. #5
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    Wow thanks a lot, that just saved me several hours of tinkering! I think I can implement your instructions. I have a few questions though. Why do I use QImage and not QPixmap? And why is it better to set the QImage as the background of a QLabel instead of having QPainter drawPixmap()-ing it in the paintEvent()?

  6. #6
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    QImage allows faster per pixel manipulation/access (=> scanline). The final conversion to a Pixmap will use implicitly shared data if your color format is acceptable.

    paintEvent of what Widget? You don't need to create a new subclass to just show an image. But if you intend to build your own heatmap widget with scales etc drawPixmap in paintEvent will do just fine/better!

    BTW: I don't think you got the concept of a LUT yet.. For its creation, you won't need a progressbar! If you have a lot of pixels, lot's of them will have the same color, because they have the same value within a given resolution. The idea of a LUT is to do the following: color = LUT[qround(value)]; So the LUT is just an array of increasingly 'hotter' colors in your case.. Depending on the number of pixels, usage of a color-LUT can be a big time saver. If you say you want to differentiate 10k heat-values, you need to calculate the color values only for 10k values instead for 640x480 ~ 300k values.

    Joh

  7. #7
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    Yo, drawPixmap works like a charm. My widget draws in no time now and even resizing is not a problem. The heat map is in place. Well almost.
    On top of the pixel by pixel heat map I draw little circles to mark special points, like peaks of mountains. The circles used to look really nice with painter.setRenderHint(QPainter::Antialiasing, true), but now they look really bad on the pixmap. If I turn the anti aliasing on, somehow my desktop wallpaper is mixed into the pixmap.

    About the LUT, unfortunately I can't optimize it the way you suggest. There is no way around calculating the "heat" for every single pixel individually and that is what costs time. The linear interpolation between two colors to represent the heat value doesn't change anything compared to that.

  8. #8
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    If you use your own custom widget for the painting.. you won't need the displayimage, necessarily. Just drawPixmap the heatimage on the widgets painter. and then directly draw your circles. Does that work?

    LUT: Well it adds up. And it depends on how often you need to refresh your heatimage. But it seems pretty stationary in your case. So forget about it. I had 2560x1600 realtime changing pixels where it made a BIG difference..

  9. #9
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    387
    Thanks
    101
    Thanked 15 Times in 15 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    Yes it does work.

    Well, maybe after everything else is done I will tinker with the LUT and see how much it does. But I doubt it will be noticable. Compared to the 300k times 1 ms for each pixel of the heat map, reducing 300k linear interpolations to 10k look ups is most likely less than 0.1 percent of the total runtime.

    Thanks for the help mate! We put this thing together in less than two hours.

  10. #10
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Painting of lots of computationally heavy pixels

    Well it went that fast because you didn't need any help implementing. Good work!

    BTW: If you want to do me a favour, use the forums thanks button, once :->

    Bye!

    Johannes

  11. The following user says thank you to JohannesMunk for this useful post:

    Cruz (11th April 2010)

Similar Threads

  1. Pixels
    By Dante in forum Qt Programming
    Replies: 1
    Last Post: 21st April 2009, 20:50
  2. Replies: 4
    Last Post: 11th December 2008, 17:35
  3. Screen refresh during heavy computation
    By martinb0820 in forum Qt Programming
    Replies: 5
    Last Post: 17th November 2008, 22:20
  4. Qt 4.3.0 lots of Bugs!
    By VireX in forum Qt Programming
    Replies: 69
    Last Post: 20th June 2007, 22:05
  5. Application very heavy for lots object
    By Kapil in forum Newbie
    Replies: 1
    Last Post: 29th April 2006, 17:33

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.