Qt World Summit: Register Today!


Qt image resource is null



  • Hi folks
    It seems like this has been posted and asked a lot, but I've done just about every step I can find, and nothing is working, so I need help!
    I need to set an image as a qt resource, and load it in as the background of a Qchart.

    So here's what I've done:
    Saved the image into a sub-directory in my program.
    created a qrc file named resources.qrc. Here's the contents of that file:

    <RCC>
        <qresource>
        <file>images/scribble.jpg</file>
        </qresource>
    </RCC>
    

    Modified the .pro file with the following contents:

    RESOURCES += extra/resources.qrc
    

    Attempted to load the file with the following code, and done some null checking:

    QImage my_image(":/images/scribble.jpg");
    if(my_image.isNull())
    {
        outputTextBox->append("image is null");
    }
    

    I've also tried:

        QImage my_image;
        my_image.load(":/images/scribble.jpg");
    

    I've completely removed my build folder on the build system and re-initialized the repo and rebuilt the code, but that isn't changing anything either.

    I've confirmed it's finding the resources.qrc by changing both the name and filepath of the qrc file, which throws errors when I run qmake ---.pro
    I've also changed the filepath in the code, i.e. QImage my_image(":/images/scrible.jpg"); or QImage my_image(":/imag/scribble.jpg"); which results in Qt throwing an error on the command line that says the image is not found at runtime. (note the intentional spelling errors)

    So it seems to me that it's finding the image and qrc file, but despite that, is not able to load it in for some reason.
    What am I doing wrong??


  • Lifetime Qt Champion

    Do you actually add the resource to your application?


  • Lifetime Qt Champion

    Hi,

    Can you show the structure of your project ?

    Did you try to load the file from the disk just to check that it loads properly ?



  • @Christian-Ehrlicher
    Yes, it's in a folder, available to the application. Like I mentioned, if I change the filepath or name in the code, it throws an error saying it can't find it - so it does seem to be finding it but isn't reading it somehow?



  • @SGaist

    My project structure is:

    project
    -headers
    *.h
    -sources
    -main.cpp
    *.cpp (file that calls the image is in here)
    -extra
    -resources.qrc
    -images
    -scribble.jpg

    I think that's all the relevant info on my structure. What's a way to load the file from disk to see that my program sees it?



  • @Kelenyche said in Qt image resource is null:

    @SGaist

    My project structure is:

    project
    -headers
    *.h
    -sources
    -main.cpp
    *.cpp (file that calls the image is in here)
    -extra
    -resources.qrc
    -images
    -scribble.jpg

    I think that's all the relevant info on my structure. What's a way to load the file from disk to see that my program sees it?

    Oh none of my nice spacing came through lol.


  • Lifetime Qt Champion

    Try editing it with coding tags.

    For the test, just use the full path to the file on the disk.



  •  project
         headers
             *.h
         sources
             main.cpp
             *.cpp (file that calls the image is in here)
         extra
             resources.qrc
             images
                 scribble.jpg
    

    I'll try the full disk path.



  • Full disk path is also coming up with a null image.

    Fwiw, I'm doing this on a raspberry pi, is it possible there's some permission problems?


  • Lifetime Qt Champion

    Next step: start your application with the QT_DEBUG_PLUGINS environment variable set to 1 to see what's going on with the image plugins.



  • @SGaist
    Where should this be set? I'm also doing all this off the command line, no qt creator. Would this be in the .pro file, or an argument called with qmake program.pro?


  • Lifetime Qt Champion

    On the command line directly



  • Ah, ok so I ran:
    QT_DEBUG_PLUGINS=1 ./program
    and it dumped a bunch of info. I'm not seeing any problems or failures in here...?

    Got keys from plugin meta data ("ico", "cur")
    QFactoryLoader::QFactoryLoader() looking at "/usr/lib/aarch64-linux-gnu/qt5/plugins/imageformats/libqjpeg.so"
    Found metadata in lib /usr/lib/aarch64-linux-gnu/qt5/plugins/imageformats/libqjpeg.so, metadata=
    {
        "IID": "org.qt-project.Qt.QImageIOHandlerFactoryInterface",
        "MetaData": {
            "Keys": [
                "jpg",
                "jpeg"
            ],
            "MimeTypes": [
                "image/jpeg",
                "image/jpeg"
            ]
        },
        "className": "QJpegPlugin",
        "debug": false,
        "version": 330499
    }
    

    This seems like the most relevant portion, but again it seems to have succeeded in recognizing jpgs, so I don't see a problem. Let me know if there's anything else I should be looking for. I'm not seeing parts that are specific to my code, it just looks like Qt's background stuff for loading certain plugins.



  • @Kelenyche said in Qt image resource is null:

    Ah, ok so I ran:
    QT_DEBUG_PLUGINS=1 ./program
    and it dumped a bunch of info. I'm not seeing any problems or failures in here...?

    Got keys from plugin meta data ("ico", "cur")
    QFactoryLoader::QFactoryLoader() looking at "/usr/lib/aarch64-linux-gnu/qt5/plugins/imageformats/libqjpeg.so"
    Found metadata in lib /usr/lib/aarch64-linux-gnu/qt5/plugins/imageformats/libqjpeg.so, metadata=
    {
        "IID": "org.qt-project.Qt.QImageIOHandlerFactoryInterface",
        "MetaData": {
            "Keys": [
                "jpg",
                "jpeg"
            ],
            "MimeTypes": [
                "image/jpeg",
                "image/jpeg"
            ]
        },
        "className": "QJpegPlugin",
        "debug": false,
        "version": 330499
    }
    

    This seems like the most relevant portion, but again it seems to have succeeded in recognizing jpgs, so I don't see a problem. Let me know if there's anything else I should be looking for. I'm not seeing parts that are specific to my code, it just looks like Qt's background stuff for loading certain plugins.

    This chunk also seems like it recognized that it needs jpgs:

    Got keys from plugin meta data ("svg", "svgz")
    QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/Desktop/program/imageformats" ...
    loaded library "/usr/lib/aarch64-linux-gnu/qt5/plugins/imageformats/libqjpeg.so"
    QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/aarch64-linux-gnu/qt5/plugins/accessible" ...
    QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/Desktop/program/accessible" ...
    QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/aarch64-linux-gnu/qt5/plugins/accessiblebridge" ...
    QFactoryLoader::QFactoryLoader() checking directory path "/home/pi/Desktop/program/accessiblebridge" ...
    QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/aarch64-linux-gnu/qt5/plugins/iconengines" ...
    QFactoryLoader::QFactoryLoader() looking at "/usr/lib/aarch64-linux-gnu/qt5/plugins/iconengines/libqsvgicon.so"
    Found metadata in lib /usr/lib/aarch64-linux-gnu/qt5/plugins/iconengines/libqsvgicon.so, metadata=
    {
        "IID": "org.qt-project.Qt.QIconEngineFactoryInterface",
        "MetaData": {
            "Keys": [
                "svg",
                "svgz",
                "svg.gz"
            ]
        },
        "className": "QSvgIconPlugin",
        "debug": false,
        "version": 330499
    }
    

  • Lifetime Qt Champion

    That part looks good.
    And I am guessing that it also says somewhere that the plugin was successfully loaded ?

    The next step: did you check that the file is a valid jpeg ?



  • Yea I can't find any problems in that debug info, no failures or anything.

    I actually created the jpg in paint, it's literally just some scribbles. I have a .png I've been trying to use but no luck, so I wanted to try a different file type, with a differently formatted name to see if anything would change. I don't see how it wouldn't be a valid jpg, having just saved it from paint?


  • Lifetime Qt Champion

    Getting really strange...

    No special characters in the path ? Not that it should play a role but who knows...

    If you use QFile to open it, does it work ?



  • Nope, the full path is: "/home/pi/Desktop/program/extra/images/scribble.jpg"

    Alright I'm not familiar with QFile, but I used:

    QFile testfile("/home/pi/Desktop/program/extra/images/scribble.jpg");
    
    if(testfile.exists())
    {
        outputTextBox->append("opened the file");
    }
    

    and it seems to have succeeded.
    will testfile.exists() do the same test as isNull in QImage?


  • Lifetime Qt Champion

    No, it just confirms the existence of the file not whether it is valid.

    Use the QImageReader class. It's lower level but may give you more information about what is going wrong.



  • Ok so I have:

    QImage testimage(64,64,QImage::Format_RGB32);
    QImageReader reader("/home/pi/Desktop/program/extra/images/scribble.jpg");
    
    if(reader.read(&testimage))
    {
        outputTextBox->append("opened the file");
    }
    

    It's telling me the file is good now...


  • Lifetime Qt Champion

    Within the same application, do you have the same issue if you load a different QImage variable using the usual way ?



  • I think so - I initially tried with the png, then switched to the jpg, and neither one is doing what I expect, so I think they're both coming in null with QImage.



  • Ooh, I think I'm onto something. So the way my code was implemented, I read the image, did some resizing and stuff, then was checking if it was null after that, since my textbox wasn't added to the gui yet. I switched to QDebug since that's more handy, and moved that code up - it looks like my resizing stuff was causing the image to become null? I now have a not-resized image that's painting onto the background of the graph!

    I'll post my full fix once I figure this out. :)



  • Yep, this chunk is causing it to become null:

        int chart_width = static_cast<int>(splineChart->plotArea().width());
        int chart_height = static_cast<int>(splineChart->plotArea().height());
        int view_width = static_cast<int>(splineChartView->width());
        int view_height = static_cast<int>(splineChartView->height());
        scribble = scribble.scaled(QSize(chart_width, chart_height));
    

    So in QImage::scaled, if width or height are zero, it returns a null QImage. For some reason, my width and height are returning 0, so that makes sense. Sorry for the wild goose chase, and thank you for your help!



  • Sorry to re-open this topic. I recently encountered the same issue. When using QFile to check file size, it returns the correct value. But when I use QImage or QImageReader, the size is always QSize(0, 0) or null.

    Not like @Kelenyche , I didn't call QImage::scaled() to manipulate the image size.

    Following @SGaist 's suggestion, I set the QT_DEBUG_PLUGINS=1 environment variable and run the program, the output didn't seem like to provide anything useful:

    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/platforms" ...
    QFactoryLoader::QFactoryLoader() looking at "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-debug-visual-
    studio/plugins/platforms/qwindowsd.dll"
    Found metadata in lib C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-debug-visual-studio/plugins/platform
    s/qwindowsd.dll, metadata=
    {
        "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3",
        "MetaData": {
            "Keys": [
                "windows"
            ]
        },
        "archreq": 1,
        "className": "QWindowsIntegrationPlugin",
        "debug": true,
        "version": 393728
    }
    
    
    Got keys from plugin meta data QList("windows")
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/platforms" ...
    loaded library "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-debug-visual-studio/plugins/platforms/qwin
    dowsd.dll"
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/platformthemes" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/platformthemes" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/styles" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/styles" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/accessible" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/accessible" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/imageformats" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/imageformats" ...
    qDebug: background image is null?  true
    qDebug: background image size?  QSize(0, 0)
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/plugins/accessiblebridge" ...
    QFactoryLoader::QFactoryLoader() checking directory path "C:/Users/zhongdongy/Workspace/repos/qt-family-hub/cmake-build-
    debug-visual-studio/accessiblebridge" ...
    

    Note: this is a PNG file, so I assume it will not load the QJpeg plugin.

    The QFile::size() function returns the file size correctly, so the embedded resource definitely exists and loaded.

    I'm using Qt6 with MSVC (something wrong when linking using mingw) on Windows 11 x64, and font resources have no such issue, only image files.


  • Lifetime Qt Champion

    There is no Qt png plugin because the support for png is built-in in QtGui so no plugin needed. Therefore it's also not a plugin problem but a problem of your path passed to QFile.



  • @Christian-Ehrlicher Thanks for the response. But the path passed to QFile and QImage or QImageReader are exactly the same. Even when I use the following approach still cannot get a usable QImage instance:

      QFile f(":/resources/images/default-background.png");
      f.open(QIODevice::OpenModeFlag::ReadOnly);
      QByteArray byte_array = f.readAll();
      qDebug() <<"Bytes length: " << byte_array.length();
      QImage img = QImage::fromData(byte_array);
      qDebug() << "Is QImage instance null: " << img.isNull();
    

    The output:

    Bytes length:  277370
    Is QImage instance null:  true
    

    So the path is definitely correct.



  • @zhongdongy What if you pass the path to the file into QImage constructor? Get rid of the middle man QByteArray.



  • @artwaw Thanks for the suggestion. Originally I did use the QImage constructor directly. But it didn't work. So I use QFile to read QByteArray to prove the path is correct.



  • Here is a sample demonstrating the issue I encountered: GitHub | qt-forum-samples/qimage-not-loading. It's based on the reply I posted above. I'm building this project using MSVC, so the CMakeLists.txt file has some extra jobs to copy the debug DLLs.


  • Lifetime Qt Champion

    Works fine for me after I removed the strange rcc custom command. You enabled CMAKE_AUTORCC so why to you the call rcc by yourself? Remove it and simply add application.qrc to your list of sources as described in the documentation of CMAKE_AUTORCC.



  • @Christian-Ehrlicher The custom command was added because I once suspected the CMAKE_AUTORCC was not working correctly. Just now as you suggested, I commented the custom Cmake command, but still no luck.

    It is very clear now, this command has nothing to do with the QImage not loading data but thank you anyway. It somehow just failed on my laptop, I'll try to start a Linux virtual machine and see how.

    May I know your Qt version? Mine is Qt 6.2.3.


  • Lifetime Qt Champion

    My Qt version is 5.15.2 on Linux and 6.2.3 on Win (MinGW)

    Bytes length:  277370
    qt.gui.icc: fromIccProfile: failed minimal tag size sanity
    Is QImage instance null:  false
    qt.gui.icc: fromIccProfile: failed minimal tag size sanity
    Is QImage2 instance null:  false
    


  • @Christian-Ehrlicher Thank you very much. From what we've seen now, the code itself has no issue. I'll try on Linux, or other versions on Windows and see how. I'll update here if I found something.



  • @Christian-Ehrlicher Just now I use a Linux (Ubuntu 21.10) vm to test the same code with GCC, same result as you've posted:

    Warning: Ignoring WAYLAND_DISPLAY on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
    Bytes length:  277370
    qt.gui.icc: fromIccProfile: failed minimal tag size sanity
    Is QImage instance null:  false
    qt.gui.icc: fromIccProfile: failed minimal tag size sanity
    Is QImage2 instance null:  false
    

    And I've already re-installed Windows 11 (code failed) now using Windows 10 host (also failed). This is really frustrating because I'll have to write Qt on a Windows host and compile it inside Linux vm, lol. I cannot use Linux directly because the Intel Iris Xe graphics card shipped with Intel i7-1195G7 has screen tearing issue on almost all Linux distros (Fedora, Arch, Ubuntu, Debian, RH, Deepin...). Spent the whole day yesterday to install and test...

    I'll try submit a bug report on bugtracker if none submitted before. Thanks everyone.


Log in to reply