[Solved]QImage fail to read jpeg--dll deploy problem



  • imageAccessManager.hpp
    @
    /*

    • get and save the image from network
      */
      class imageAccessManager : public QObject
      {
      Q_OBJECT
      public:
      explicit imageAccessManager(QObject *parent = 0);

      imageAccessManager(imageAccessManager const&) = delete;
      imageAccessManager& operator=(imageAccessManager const&) = delete;

      void request_image(QString const &url);

    private slots:
    void save_image();

    private:
    QString const get_image_name(QString const &url) const{
    return url.mid(url.lastIndexOf("/") + 1);
    }

    QString const get_image_type(QString const &url) const{
        return url.mid(url.lastIndexOf(".") + 1);
    }
    

    private:
    QNetworkAccessManager *manager_;
    };
    @

    imageAccessManager.cpp
    @
    #include "imageAccessManager.hpp"

    imageAccessManager::imageAccessManager(QObject *parent) :
    QObject(parent), manager_(new QNetworkAccessManager(this) )
    {
    }

    void imageAccessManager::request_image(QString const &url)
    {
    QDir dir(QDir::currentPath() );
    if(dir.exists(get_image_name(url)) ) return;

    QNetworkReply *reply = manager_->get(QNetworkRequest(url) );
    connect(reply, SIGNAL(finished()), this, SLOT(save_image()) );
    

    }

    void imageAccessManager::save_image()
    {
    QNetworkReply reply = qobject_cast<QNetworkReply>(sender() );
    reply->deleteLater();

    if(reply->error() != QNetworkReply::NoError)
    {
        qDebug() << reply->errorString();                
        return;
    }   
    
    QImage image;
    image.loadFromData(reply->readAll() );
    QString const image_url = reply->url().toString();
    if(image.isNull() )
    {
        qDebug() << reply->readAll().size();
        qDebug() << "image " << image_url << "is null";
    
        return;
    }
    
    if(get_image_type(image_url).compare("gif", Qt::CaseInsensitive) == 0)
    {
        qDebug() << "do not support saving gif yet";
    
        return;
    }
    
    if(!image.save(get_image_name(image_url),
                  get_image_type(image_url).toLatin1() ))
    {
        qDebug() << "can not save image" << image_url;
    }
    

    }

    @

    main.cpp
    @
    #include "imageAccessManager.hpp"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    imageAccessManager manager;
    manager.request_image("http://2cat.or.tl/~tedc21thc/live/src/1345988069239.jpg");
    
    return a.exec(&#41;;
    

    }
    @

    OS : win7 64bits
    Qt version : 4.8.2
    compiler : mingw4.6.2(32bits)

    I could get the image by the codes on my computer
    But when I release the binary to other computer
    it always respond "image xxx is null", and the size of
    the QByteArray is always "0".

    Even I execute the program as "administrator" and turn off
    the firewall, the size of the QByteArray is always zero.

    What is happening?



  • I just realize that after the call of reply->readAll, the reply would not hold the data anymore
    So I change the codes at line 28~37 as follow
    @
    QImage image;
    image.loadFromData(reply->readAll() );
    qDebug() << image.size(); //the size will be 1440, 810 on my pc
    //the image could be save too
    QString const image_url = reply->url().toString();
    if(image.isNull() )
    {
    qDebug() << "image " << image_url << "is null";

        return;
    }
    

    @

    But on my virtual box, and other's computer, the size will be (0, 0) even the size of
    the buffer are the same.Yes, the size of the buffer on my computer, virtual box and
    other pc are the same, but only my computer can save the image.
    Do QImage need another library to save jpg?



  • No, it does not need a special library. Assuming that get_image_name(image_url) produces a valid file name (without path) for the host system the file will be written into the current working directory of the process. On Windows 7 attempts to write to protected locations will either fail (manifest in program) or be redirected (no manifest). Either way the file will not be where you expect it. Check this first.



  • Thanks for your reply, but the problem is not because it can't save the image but the
    QImage failed to recognize "it is a jpg"

    @
    //the QImage is "null " even the size of the QByteArray are the same, on my
    //PC, virtual box, and the other's PC
    image.loadFromData(reply->readAll() );
    @

    @
    image.loadFromData(reply->readAll(), "jpg"); //still fail
    @

    Whatever, the size of the QImage is always (0, 0) on other pc
    but my pc work perfectly good, don't know what is happening


  • Moderators

    Let's debug, step-by-step.

    First, pass the result of QNetworkReply->readAll() to QFile::write(). Has the image downloaded correctly? Can you open the image in your computer?

    If it doesn't work, then something's wrong with the download.
    If it does works, then the problem is not in QNetworkAccessManager (so you should change your title).

    Also, please provide details on how you "release the binary to other computer"?



  • Thanks for your advices, I change the codes to

    @
    QImage image;
    QString const image_url = reply->url().toString();
    QByteArray image_array = reply->readAll();
    image.loadFromData(image_array); //fail to load the image_array

    QFile file&#40;"temp"&#41;;
    
    if ( !file.exists()) qDebug() << "can't find";
    
    if(!file.open(QIODevice::WriteOnly) ) qDebug() << "can't open";
    
    file.write(image_array); //but the data could be save and display by other software
    

    @

    Maybe I should change the title to "QImage fail to read jpeg"



  • Chances are you have not deployed the image format plugins (not that you really need them to save the downloaded image as JKSH points out).



  • I release my program with the items as follow

    1 : release with the exe compile by mingw4.6.2
    2 : put other's dll in the same folder
    libgcc_s_dw2-1.dll, libstdc++-6.dll, mingwm10.dll, QtCore4.dll, QtGui4.dll, QtNetwork4.dll

    Test it on Virtual box and other pc, make sure it has the same behaviour on my pc


  • Moderators

    Yup, that's a better title :) whi



  • I make the codes become easier to read
    @
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    QImage image("temp.jpg");
    qDebug() << image.size(); //the size is (0, 0) even the jpg can be read by other software
    image.save("haha");
    
    return a.exec(&#41;;
    

    }
    @

    on my pc, it works prefectly, but other pc just don't work


  • Moderators

    Interesting...

    Try this and see if you can get any useful info:
    @
    qDebug() << "Supported formats:" << QImageReader::supportedImageFormats();

    QImageReader reader("temp.jpg");
    qDebug() << "Can read file?:" << reader.canRead();

    QImage image = reader.read();
    qDebug() << reader.errorString();
    @



  • Weird, extremely weird,same dll, same exe, same os

    on my pc, the answer are

    bq. Supported formats: ("bmp", "gif", "ico", "jpeg", "jpg", "mng", "pbm", "pgm", "pn
    g", "ppm", "svg", "svgz", "tga", "tif", "tiff", "xbm", "xpm")
    Can read file?: true
    "Unknown error"

    on other pc, the answer are

    Supported formats: ("bmp", "pbm", "pgm", "png", "ppm", "xbm", "xpm")
    Can read file?: false
    "Unsupported image format"


  • Moderators

    Try copying C:[Qt-installation]\4.8.2\plugins\qjpeg4.dll



  • I copy the dll of plugins into the folder, but the QImage still don't support jpg


  • Moderators

    http://www.qtcentre.org/threads/32614-DLL-Deploying-problems

    Sounds like they succeeded when they put qjpeg4.dll inside a subdirectory called "imageformats"



  • Thanks a lot, the problem solved.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.