Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
QImageReader second read() results in empty image
MichMich last edited by MichMich
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 Creator 4.8.0
JonB last edited by JonB
For a start check the return result of
reader.device()->seek(0). Though if it returns
falseI don't know what you're going to do about it.
Since your question has gone unanswered, unless you want to look through the
QImageIOHandler) source code, you may have to guess that it's not aware of your "seek" alteration, e.g. perhaps
QImageReaderassumes exclusive control over the file or device that is assigned. Any attempts to modify the assigned file or device during the lifetime of the
QImageReaderobject will yield undefined results.
and perhaps create a new
QImageReaderoff the file again instead.
You could also try setFileName
It might reset state of the reader.
MichMich last edited by
Hallo, thank's for the response.
true, it sets the position correctly to 0, i checked the previouse value.
I also tried to debug into the
QImageReadersource 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:
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?
JonB last edited by
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
QImageReaderwith its image gets disposed properly so that it does not retain any memory footprint.
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 ...
JonB last edited by
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.
MichMich last edited by
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.