Details
-
Bug
-
Resolution: Duplicate
-
Not Evaluated
-
5.15.0
-
None
-
Ubuntu 18.04.4 LTS
Description
Just installed 5.15.0 version and I get strange behavior which I am not sure I fully understand. My code is working fine in 5.14.1
I am using QtConcurrent::mapped to scale images. The images are read and scaled using QImageReader and its setScaledSize.
const QFuture<QImage> resized_images = QtConcurrent::mapped(image_paths, Picture_load_scale_multithread(m_picture_size_spinbox->value())); while(!resized_images.isFinished()){...}
struct Picture_load_scale_multithread{ // constructor: Picture_load_scale_multithread(const int max_size) : m_max_width(max_size), m_max_height(max_size) {} // define output type typedef QImage result_type; // member: const int m_max_width; const int m_max_height; QImage operator()(const QString& image_path){ if(image_path.isEmpty()){ return QImage(); } QImageReader imageReader(image_path); QSize s = imageReader.size(); // s = QSize(); // UNCOMMENT TO FORCE USAGE OF QImage::scale INSTEAD OF QImageReader.setScaledSize if(s.isValid() && !s.isNull()){// use of imageReader scaling should be faster // calculate QSize to scale to, to keep Image aspect ratio (Qt::KeepAspectRatio is not a direct option with QImageReader) const qreal f = qMin(static_cast<qreal>(m_max_width)/static_cast<qreal>(s.width()), static_cast<qreal>(m_max_height)/static_cast<qreal>(s.height())); imageReader.setScaledSize(QSize(qCeil(f*static_cast<qreal>(s.width())), qCeil(f*static_cast<qreal>(s.height())))); const QImage i_scaled = imageReader.read(); // LARGE IMAGE HANGS HERE if(i_scaled.isNull()){ Pf::debug_other_log("Picture_load_scale_multithread", QObject::tr("Output of scaling picture is NULL picture, error is:\n")+imageReader.errorString()); } return i_scaled; }else{ //use QImage::scale Pf::debug_other_log("Picture_load_scale_multithread", "cannot get QSize for image : "+image_path); const QImage image = imageReader.read(); if(image.isNull()){ Pf::debug_other_log("Picture_load_scale_multithread", "Null image : "+image_path); return image; }else if(m_max_width >= image.width() && m_max_height >= image.height()){ //Avoid scaling to bigger image return image; }else{ const QImage i_scaled = image.scaled(m_max_width, m_max_height, Qt::KeepAspectRatio, Qt::SmoothTransformation); // SOME IMAGES SCALING HANGS if(i_scaled.isNull()){ Pf::debug_other_log("Picture_load_scale_multithread", QObject::tr("Output of scaling picture is NULL picture")); } return i_scaled; } } //return QImage(); never reached } };
This works if I have filters to return only a limited number of pictures whatever those picture sizes are.
But if I have a larger number of pictures and among those some are of large size then QImageReader never returns.
I manage to found some of the pictures which failed and if I scale them down to 2024x1024 in GIMP (originial is 4288x2848 pixels) then the rescaled ones are properly loaded the remaining large ones continue to fail.
I have tried to force usage of image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation) instead as shown in code above. In this case image.scaled is also hanging but on even larger number of images than with the setScaledSize(). This alternative also works perfectly fine in 5.14.1.
In both cases, given QImageReader never returns, QtConcurrent::mapped QFuture result isFinished() is never true and the application freeze.
PC memory usage is not changing during the rescaling process and is around 40% during my tests.
Attachments
Issue Links
- duplicates
-
QTBUG-84619 Use of global thread pool for image conversion is changes behavior in Qt5.15
- Closed