QPixmap::load has wrong about the image data.



  • I have one image file, filename is 72036.jpg, but when i use the bash command file 72036.jpg to see

    $ file 72036.jpg
    72036.jpg: PNG image data, 640 x 960, 8-bit/color RGB, non-interlaced
    

    Note file name is 72036.jpg but the image data is PNG.

    when I use the QPixmap::load(filename) the function return false;
    when I use the QPixmap::load(filename, "png") the function return true;

    I saw the QPixmap manual

    bool QPixmap::load(const QString &fileName, const char *format = Q_NULLPTR, Qt::ImageConversionFlags flags = Qt::AutoColor)
    Loads a pixmap from the file with the given fileName. Returns true if the pixmap was successfully loaded; otherwise invalidates the pixmap and returns false.
    The loader attempts to read the pixmap using the specified format. If the format is not specified (which is the default), the loader probes the file for a header to guess the file format.
    The file name can either refer to an actual file on disk or to one of the application's embedded resources. See the Resource System overview for details on how to embed pixmaps and other resource files in the application's executable.

    The loader attempts to read the pixmap using the specified format. If the format is not specified (which is the default), the loader probes the file for a header to guess the file format.

    I think Qt guess wrong!

    But, I Confused, when i saw the following result.

    void Fun()
    {
        /** some code at here  */
        QPixmap pixmap1,pixmap2;
        QString filename = "72036.jpg";
        if( !pixmap1.load( filename ) ) ///< return false
        {
        }
        if( !pixmap2.load( filename) )  ///< return false
        {
        }
    
        ...
    }
    
    
    void Fun1()
    {
        /** some code at here  */
        QPixmap pixmap1,pixmap2;
        QString filename = "72036.jpg";
        if( !pixmap1.load( filename, "png" ) ) ///< return true; I get it.
        {
        }
        if( !pixmap2.load( filename) )  ///< it also return true ?  I confused! Qt is intelligent ?
        {
        }
    
        ...
    }
    

    My Qt version is 5.7.0.

    About this case, and How to do ?


  • Moderators

    @joeQ said in QPixmap::load has wrong about the image data.:

    I saw the QPixmap manual
    ...
    The loader attempts to read the pixmap using the specified format. If the format is not specified (which is the default), the loader probes the file for a header to guess the file format.

    I think Qt guess wrong!

    The documentation is wrong.

    See the Qt source code at https://code.woboq.org/qt5/qtbase/src/gui/image/qpixmap.cpp.html#_ZN7QPixmap4loadERK7QStringPKc6QFlagsIN2Qt19ImageConversionFlagEE

    If the format is not specified, Qt first uses the file extension to guess the format. Your extension is ".jpg", so Qt thinks it is a JPEG file.

    But, I Confused, when i saw the following result.

        QPixmap pixmap1,pixmap2;
        QString filename = "72036.jpg";
        if( !pixmap1.load( filename, "png" ) ) ///< return true; I get it.
        {
        }
        if( !pixmap2.load( filename) )  ///< it also return true ?  I confused! Qt is intelligent ?
        {
        }
    

    The data is cached.

    pixmap1 already loaded the file successfully, so pixmap2 doesn't need to re-load the file. Instead, pixmap2 shares the same data as pixmap1. You can also see this in the Qt source code.



  • @JKSH First, Very very very Thank you.

    I want to used the following way to save my problem. but has some questions.

    QList<QByteArray> QImageReader::supportedImageFormats()

    qDebug:("bmp", "cur", "dds", "gif", "icns", "ico", "jpeg", "jpg", "pbm", "pgm", "png", "ppm", "svg", "svgz", "tga", "tif", "tiff", "wbmp", "webp", "xbm", "xpm")

     
    void Fun()
    {
        int i = 0;
        QPixmap pixmap;
        QString str, qsToolTip, qsFilePath="72036.jpg";
        QList<QByteArray> ltFmts;
    
        const char *pfmt;
        bool bloadOk = false;
    
        bloadOk = pixmap.load(qsFilePath,);
        if( !bloadOk )
        {
            ltFmts = QImageReader::supportedImageFormats(); ///< get the qt support image fotmat
            //qDebug() << ltFmts;
            i=0;
            do{
                ///< try every image format
                bloadOk = false;
                pfmt = ltFmts.at(i).constData();
                bloadOk = pixmap.load( qsFilePath, pfmt); ///< when pfmt = "icns", has the Assert
                i++;
            }while(!bloadOk && i < ltFmts.count() );
        }
    
        if( !bloadOk )
        {
            QMessageBox::warning(NULL, tr(""), str, QMessageBox::Yes);
        }
    }
    
    

    Assert

    parseIconEntryInfo(): Failed, OSType doesn't match: "?PNG"
    ASSERT failure in QVector<T>::at: "index out of range", file c:\Users\qt\work\install\include/QtCore/qvector.h, line 425
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.

    where is better way?


  • Qt Champions 2016

    @JKSH said in QPixmap::load has wrong about the image data.:

    The documentation is wrong.

    We really need to fix this.



  • Hi,
    you could load your pixmap this way:

       QPixmap p;
       QImageReader r(filename);
       r.setDecideFormatFromContent(true);
       QImage i = r.read();
       if (!i.isNull())
          p = QPixmap::fromImage(i);
    
    


  • @Gerd @JKSH
    It is Ok! Thank you. Best wish for you.


Log in to reply
 

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