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 17 Dec 2018, 15:16 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

    J M 2 Replies Last reply 19 Dec 2018, 10:18
    0
    • M MichMich
      17 Dec 2018, 15:16

      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

      J Offline
      J Offline
      JonB
      wrote on 19 Dec 2018, 10:18 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
        17 Dec 2018, 15:16

        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

        M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 19 Dec 2018, 14:36 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 19 Dec 2018, 22:57 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?

          J 1 Reply Last reply 20 Dec 2018, 09:40
          0
          • M MichMich
            19 Dec 2018, 22:57

            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?

            J Offline
            J Offline
            JonB
            wrote on 20 Dec 2018, 09:40 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 20 Dec 2018, 12:30 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

              J 1 Reply Last reply 20 Dec 2018, 12:43
              3
              • Christian EhrlicherC Christian Ehrlicher
                20 Dec 2018, 12:30

                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 ...

                J Offline
                J Offline
                JonB
                wrote on 20 Dec 2018, 12:43 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 20 Dec 2018, 12:50 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 20 Dec 2018, 17:47 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

                    1/9

                    17 Dec 2018, 15:16

                    • Login

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