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. QImageReader second read() results in empty image
Forum Updated to NodeBB v4.3 + New Features

QImageReader second read() results in empty image

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 1.7k Views 2 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.
  • M Offline
    M Offline
    MichMich
    wrote on last edited by MichMich
    #1

    Hallo,

    I currently implementing a map viewer utilizing QImageReader. Everything works well until i call the read() method a second time.

    QImageReader reader( "../../../../in/image.jpg");
    reader.setClipRect(QRect(0, 0, 1500, 800));
    reader.canRead(); //returns true
    
    QImage image = reader.read();
    

    up to now everything works well.

    reader.device()->seek(0); 
    reader.setClipRect(QRect(0, 0, 500, 400));
    reader.canRead(); // returns false
    
    QImage temp_image = reader.read(); // null image
    

    The second read() call results in a null image. I already tried to fix the problem reseting the handler using reader.device()->seek(0);
    But the result was the same - no image.

    Calling error() or errorString() before the second call of read() always returns "Unknown error". After the second read() call the method returns "Unable to read image data".

    I working with:
    Qt 5.12.0
    Qt Creator 4.8.0
    macOS 10.14

    Thanks

    JonBJ mrjjM 2 Replies Last reply
    0
    • M MichMich

      Hallo,

      I currently implementing a map viewer utilizing QImageReader. Everything works well until i call the read() method a second time.

      QImageReader reader( "../../../../in/image.jpg");
      reader.setClipRect(QRect(0, 0, 1500, 800));
      reader.canRead(); //returns true
      
      QImage image = reader.read();
      

      up to now everything works well.

      reader.device()->seek(0); 
      reader.setClipRect(QRect(0, 0, 500, 400));
      reader.canRead(); // returns false
      
      QImage temp_image = reader.read(); // null image
      

      The second read() call results in a null image. I already tried to fix the problem reseting the handler using reader.device()->seek(0);
      But the result was the same - no image.

      Calling error() or errorString() before the second call of read() always returns "Unknown error". After the second read() call the method returns "Unable to read image data".

      I working with:
      Qt 5.12.0
      Qt Creator 4.8.0
      macOS 10.14

      Thanks

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #2

      @MichMich
      For a start check the return result of reader.device()->seek(0). Though if it returns false I don't know what you're going to do about it.

      Since your question has gone unanswered, unless you want to look through the QImageReader (QImageIOHandler) source code, you may have to guess that it's not aware of your "seek" alteration, e.g. perhaps

      Note: QImageReader assumes exclusive control over the file or device that is assigned. Any attempts to modify the assigned file or device during the lifetime of the QImageReader object will yield undefined results.

      and perhaps create a new QImageReader off the file again instead.

      1 Reply Last reply
      1
      • M MichMich

        Hallo,

        I currently implementing a map viewer utilizing QImageReader. Everything works well until i call the read() method a second time.

        QImageReader reader( "../../../../in/image.jpg");
        reader.setClipRect(QRect(0, 0, 1500, 800));
        reader.canRead(); //returns true
        
        QImage image = reader.read();
        

        up to now everything works well.

        reader.device()->seek(0); 
        reader.setClipRect(QRect(0, 0, 500, 400));
        reader.canRead(); // returns false
        
        QImage temp_image = reader.read(); // null image
        

        The second read() call results in a null image. I already tried to fix the problem reseting the handler using reader.device()->seek(0);
        But the result was the same - no image.

        Calling error() or errorString() before the second call of read() always returns "Unknown error". After the second read() call the method returns "Unable to read image data".

        I working with:
        Qt 5.12.0
        Qt Creator 4.8.0
        macOS 10.14

        Thanks

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

        @MichMich
        Hi
        You could also try setFileName
        It might reset state of the reader.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MichMich
          wrote on last edited by
          #4

          Hallo, thank's for the response.

          @JonB
          reader.device()->seek(0) returns true, it sets the position correctly to 0, i checked the previouse value.
          I also tried to debug into the QImageReader source but i couldn't jump into the source. I mapped the debug path to the Qt sources, but this also doesn't work. I am currently building Qt from source to check if i can debug the reader.

          According to the error message i assume that the problem occurs in the row 1313: !d->handler->read(image).

          @mrjj
          Calling setFileName() before the second read everything works as expected. I receive an image.
          This could be a possible solution, but i am afraid that it could be adversely to the performance calling setFileName() repetitive. Each call will delete the old IODevice object and create a new one.

          Some background to my tool:
          My map viewer should be able to load large images. Also i have enough RAM and loading 1GB images should be now problem (but i didn't tested it up to now), i want to allow to load even larger images if necessary. I use setClipRect() to get a part of the image. If the user pans the image i want to dynamically load the according part of the image shifted by a delta. But i think i have to try calling setFileName() repetitive and check the performance.

          Or does someone have another advice?

          JonBJ 1 Reply Last reply
          0
          • M MichMich

            Hallo, thank's for the response.

            @JonB
            reader.device()->seek(0) returns true, it sets the position correctly to 0, i checked the previouse value.
            I also tried to debug into the QImageReader source but i couldn't jump into the source. I mapped the debug path to the Qt sources, but this also doesn't work. I am currently building Qt from source to check if i can debug the reader.

            According to the error message i assume that the problem occurs in the row 1313: !d->handler->read(image).

            @mrjj
            Calling setFileName() before the second read everything works as expected. I receive an image.
            This could be a possible solution, but i am afraid that it could be adversely to the performance calling setFileName() repetitive. Each call will delete the old IODevice object and create a new one.

            Some background to my tool:
            My map viewer should be able to load large images. Also i have enough RAM and loading 1GB images should be now problem (but i didn't tested it up to now), i want to allow to load even larger images if necessary. I use setClipRect() to get a part of the image. If the user pans the image i want to dynamically load the according part of the image shifted by a delta. But i think i have to try calling setFileName() repetitive and check the performance.

            Or does someone have another advice?

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by
            #5

            @MichMich
            I do not know why the code fails to re-load. But given where you are now, although resetting the filename does indeed create a new QImageReader (which then works) with some overhead, on the grand scale of things if you are going to be loading 1GB+ from disk the time to do that should way outweigh any time to re-open the file, so you may have to live with it. Make sure if you do that the previous QImageReader with its image gets disposed properly so that it does not retain any memory footprint.

            1 Reply Last reply
            1
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by Christian Ehrlicher
              #6

              Strange - looks like a jpg problem

              QImageReader reader("qticon64.jpg");
              //QImageReader reader("qticon64.png");
              reader.setClipRect(QRect(0, 0, 32, 32));
              qDebug() << "can read 1:" << reader.canRead();
              QImage image = reader.read();
              qDebug() << image;
              reader.device()->seek(0);
              qDebug() << "can read 2:" << reader.canRead();
              image = reader.read();
              qDebug() << image;
              

              Using a png file works ...

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              JonBJ 1 Reply Last reply
              3
              • Christian EhrlicherC Christian Ehrlicher

                Strange - looks like a jpg problem

                QImageReader reader("qticon64.jpg");
                //QImageReader reader("qticon64.png");
                reader.setClipRect(QRect(0, 0, 32, 32));
                qDebug() << "can read 1:" << reader.canRead();
                QImage image = reader.read();
                qDebug() << image;
                reader.device()->seek(0);
                qDebug() << "can read 2:" << reader.canRead();
                image = reader.read();
                qDebug() << image;
                

                Using a png file works ...

                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #7

                @Christian-Ehrlicher
                FYI, https://trac.ffmpeg.org/ticket/6113 reports this issue for "JPEG file seek". Though whether that's a red-herring or of some indicative interest I don't know....

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #8

                  The Qt internal QJpegHandler simply can't read a file twice due to it's internal state handling - after the image was read, the state is ReadingEnd which prevents a further re-read. Since there is also no chance to get a signal when the device read pointer was (re)set I don't see an easy way to fix it.

                  --> https://code.woboq.org/qt5/qtbase/src/plugins/imageformats/jpeg/qjpeghandler.cpp.html#_ZNK12QJpegHandler7canReadEv

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  5
                  • M Offline
                    M Offline
                    MichMich
                    wrote on last edited by
                    #9

                    I see, so the easiest way and best option according to the performance is to change from jpg files to png files.

                    I already checked it out and it works as assumed.

                    Thank you all for your help. I will mark the topic as solved.

                    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