Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-85164

Image resizing hangs

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Not Evaluated
    • Resolution: Duplicate
    • Affects Version/s: 5.15.0
    • Fix Version/s: 5.15.1
    • Component/s: Image formats
    • Labels:
      None
    • Environment:
      Ubuntu 18.04.4 LTS
    • Platform/s:
      Linux/X11

      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

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            Activity

              People

              Assignee:
              allan.jensen Allan Sandfeld Jensen
              Reporter:
              razamut razamut
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes