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. Weird QImage pixel manipulation issue.
Qt 6.11 is out! See what's new in the release blog

Weird QImage pixel manipulation issue.

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 4 Posters 4.8k 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #8

    If that is the only case then it's much more efficient to use the colour table

    inv.convertToFormat(QImage::Format_Indexed8);
    const int colCount=inv.colorCount();
    for(int i=0;i<colCount;++i){
    if(inv.color(i)==qRgba(0,0,0,0xFF)){
    inv.setColor(i,qRgba(0x33,0x33,0x33,0xFF));
    break;
    }
    }
    

    "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
    • N Offline
      N Offline
      Nicolas Kogler
      wrote on last edited by
      #9

      That actually is a great idea VRonin, as flat-styled images will never really contain more than 256 colors!

      Solved :).

      1 Reply Last reply
      0
      • N Nicolas Kogler

        Hello kshegunov,

        isn't setPixel costly? To answer your question: Only pure black images are passed to this function. The loop continuously fetches the RGBA data (i.e. 0xFF000000) and adds 0x00333333 to it -> 0xFF333333, results in a slightly brighter picture.

        I will try your method nevertheless and set this topic as "solved" if I don't find any better one. Thanks!

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

        @Nicolas-Kogler said in Weird QImage pixel manipulation issue.:

        isn't setPixel costly?

        Depends on your definition of costly. A function call, couple of ifs and a switch I don't consider to be much on the costly side.

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        2
        • N Offline
          N Offline
          Nicolas Kogler
          wrote on last edited by
          #11

          We are not necessarily talking about small images here. I believe setPixel is costly when big images are involved. But thanks for that solution, too. May come in handy for small images later! :)

          kshegunovK 1 Reply Last reply
          0
          • N Nicolas Kogler

            We are not necessarily talking about small images here. I believe setPixel is costly when big images are involved. But thanks for that solution, too. May come in handy for small images later! :)

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

            As one Donald Knuth once notably remarked:
            "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

            Which I happen to agree with. So before you know that the call to setPixel() is a bottleneck I advise you just forget this (really) tiny inefficiency.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • N Offline
              N Offline
              Nicolas Kogler
              wrote on last edited by
              #13

              @kshegunov said in Weird QImage pixel manipulation issue.:

              As one Donald Knuth once notably remarked:
              "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

              Which I happen to agree with. So before you know that the call to setPixel() is a bottleneck I advise you just forget this (really) tiny inefficiency.

              I agree, but as Niklaus Wirth once stated:
              'Software is getting slower more rapidly than hardware is getting faster.'
              I tested it now, both algorithms work and the method with 'scanline' and 'bits' is faster, so why wouldn't I take the faster one?

              btt:
              I finally found the issue (I felt like this could be it for a while) for the weird rendering, but I cannot really explain why it happened, given the fact that 'c' is copied in invertImage():

              void setImage(const QPixmap &img) {
                  QImage c = img.toImage();
                  // ... do some pixel fetching (but not manipulating) ...
                  m_pm = QPixmap::fromImage(invertImage(c));
              }
              

              now with

              void setImage(const QImage &c) {
                  // ... do some pixel fetching ...
                  m_pm = QPixmap::fromImage(invertImage(c));
              }
              

              it just works fine.

              kshegunovK 1 Reply Last reply
              0
              • N Nicolas Kogler

                @kshegunov said in Weird QImage pixel manipulation issue.:

                As one Donald Knuth once notably remarked:
                "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

                Which I happen to agree with. So before you know that the call to setPixel() is a bottleneck I advise you just forget this (really) tiny inefficiency.

                I agree, but as Niklaus Wirth once stated:
                'Software is getting slower more rapidly than hardware is getting faster.'
                I tested it now, both algorithms work and the method with 'scanline' and 'bits' is faster, so why wouldn't I take the faster one?

                btt:
                I finally found the issue (I felt like this could be it for a while) for the weird rendering, but I cannot really explain why it happened, given the fact that 'c' is copied in invertImage():

                void setImage(const QPixmap &img) {
                    QImage c = img.toImage();
                    // ... do some pixel fetching (but not manipulating) ...
                    m_pm = QPixmap::fromImage(invertImage(c));
                }
                

                now with

                void setImage(const QImage &c) {
                    // ... do some pixel fetching ...
                    m_pm = QPixmap::fromImage(invertImage(c));
                }
                

                it just works fine.

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

                @Nicolas-Kogler said in Weird QImage pixel manipulation issue.:

                I tested it now, both algorithms work and the method with 'scanline' and 'bits' is faster, so why wouldn't I take the faster one?

                Few reasons (whether they're good is up to you to decide):

                1. It depends on the internal representation of the data inside QImage which isn't guaranteed to be compatible between versions, while the Qt API is binary compatible between minor versions (that translates to years).
                2. It's a (tragic) fact of life that code is read much more than it's written, so one'd be wise to opt for more readable (and type-safe) code as every opportunity presents itself.
                3. Faster is a relative term - faster compared to what? Knuth's whole point is that you can spend months making a piece of code to run 10% faster, but if that piece of code carries 10% of the total execution time, in reality you've optimized only to remove a meager 1% of execution time. Ultimately, it boils down to profiling, finding the bottlenecks and finally removing them.

                PS.
                Talking about micro optimizations I'd suggest changing:

                inv.byteCount() / 4
                

                to:

                inv.byteCount() >> 2
                

                it isn't that clear and pretty though, is it?

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  Nicolas Kogler
                  wrote on last edited by
                  #15

                  Bitshifting is just plain beautiful <3

                  Jokes aside, of course you are totally correct. I implemented the same algorithm twice because I thought that my initial issue was caused by that. Anyways, now I am just using pixel and setPixel to interact with the data, because I agree on the readability reason with you.

                  @kshegunov said in Weird QImage pixel manipulation issue.:

                  Faster is a relative term - faster compared to what? Knuth's whole point is that you can spend months making a piece of code to run 10% faster, but if that piece of code carries 10% of the total execution time, in reality you've optimized only to remove a meager 1% of execution time. Ultimately, it boils down to profiling, finding the bottlenecks and finally removing them.

                  This is also a good point, but I guess it only applies to companies which actually only have spare development time. This is a hobby project, therefore I have plenty of time to try different stuff and play around with the features of Qt. Not to mention that I am 18 years old only and need to gain experience working with the Qt framework.

                  We shouldn't abuse this thread for these kinds of discussions anymore. You can always send me a private message, if you want. :)

                  kshegunovK 1 Reply Last reply
                  0
                  • N Nicolas Kogler

                    Bitshifting is just plain beautiful <3

                    Jokes aside, of course you are totally correct. I implemented the same algorithm twice because I thought that my initial issue was caused by that. Anyways, now I am just using pixel and setPixel to interact with the data, because I agree on the readability reason with you.

                    @kshegunov said in Weird QImage pixel manipulation issue.:

                    Faster is a relative term - faster compared to what? Knuth's whole point is that you can spend months making a piece of code to run 10% faster, but if that piece of code carries 10% of the total execution time, in reality you've optimized only to remove a meager 1% of execution time. Ultimately, it boils down to profiling, finding the bottlenecks and finally removing them.

                    This is also a good point, but I guess it only applies to companies which actually only have spare development time. This is a hobby project, therefore I have plenty of time to try different stuff and play around with the features of Qt. Not to mention that I am 18 years old only and need to gain experience working with the Qt framework.

                    We shouldn't abuse this thread for these kinds of discussions anymore. You can always send me a private message, if you want. :)

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

                    @Nicolas-Kogler said in Weird QImage pixel manipulation issue.:

                    We shouldn't abuse this thread for these kinds of discussions anymore.

                    I tend to wander off, so that happens to me a lot ... sorry.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      Nicolas Kogler
                      wrote on last edited by
                      #17

                      Sorry to put this back on top, but for anyone who has the same problem as I had:

                      The reason for the messed-up background was that after copying the image, Qt somehow converted it to a premultiplied-alpha format. Hence attempting to edit the pixels was disastrous. A call to 'convertToFormat(QImage::Format_ARGB32)' after 'copy()' should do it :).

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved