Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

Why is there no overload for QPixmap::load(QIODevice *device, ...) ?



  • Hi.
    I'm working with QNetworkDiskCache's data() method which returns a pointer to a QIODevice.

    It can be used directly with QImage::load(QIODevice *device...) to retrieve cached QImages.

    However, since I am using QPixmapCache, I want to directly store and retrieve QPixmap images from the QNetworkDiskCache as well.

    To store it in the cache, I can directly do:

        pixmap.save(cache, "XPM");
        icon_cache_->insert(cache);
    

    where cache is a QIODevice* and icon_cache_ is a QNetworkDiskCache*.

    However, to retrieve it, I need to use a QImage first, then convert it to QPixmap e.g. to insert it in the QPixmapCache:

    QImage cached_image;
    if (cached_image.load(cache.get(), "XPM")) {
        const QPixmap cached_pixmap = QPixmap::fromImage(cached_image);
        QPixmapCache::insert(cache_key, cached_pixmap);
    }
    

    From the source code in QPixmap, it is not directly clear what the actual implementation of the ::fromImage() is, but it does not seem to be a trivial operation?

    So why is there no QPixmap::load(QIODevice *device, ...) overload as is the case for QImage?. This is strange, since QPixmap does have a corresponding QPixmap::save(QIODevice *device, ...)version.

    Or is there another way to retrieve a QPixmap directly from the QNetworkCache without the need for a temporaryQImage?


  • Lifetime Qt Champion

    @Diracsbracket said in Why is there no overload for QPixmap::load(QIODevice *device, ...) ?:

    QPixmap::save(QIODevice *device, ...)

    Which also simply converts the QPixmap to a QImage. You're most likely looking for QPixmap::fromImageReader()



  • @Christian-Ehrlicher: Thanks!

    QPixmap::save(QIODevice *device, ...)

    Which also simply converts the QPixmap to a QImage.

    Indeed... However, it turns out that

    QPixmap::fromImageReader()
    

    also uses an intermediate QImage. It internally uses:

    void QPlatformPixmap::fromImageReader(QImageReader *imageReader,
                                      Qt::ImageConversionFlags flags)
    {
        const QImage image = imageReader->read();
        fromImage(image, flags);
    }
    

    The documentation for QPixmap::fromImageReader() states:

    On some systems, reading an image directly to QPixmap can use less memory than reading a QImage to convert it to QPixmap.
    

    Not sure what that means, as it always internally seems to use a QImage first. I'm not so much worried as much about memory in my case but more about doing unnecessary conversions.

    So sadly, Qt provides no way around always using a QImage in the end.


  • Lifetime Qt Champion

    @Diracsbracket said in Why is there no overload for QPixmap::load(QIODevice *device, ...) ?:

    So sadly, Qt provides no way around always using a QImage in the end.

    QPixmap can not directly be modified (i.e. pixels) so it can also not be used to directly load pixel data from files. That's what QImage is for.



  • Thanks @Christian-Ehrlicher.

    QPixmap can not directly be modified (i.e. pixels) so it can also not be used to directly load pixel data from files. That's what QImage is for.

    I have no idea about the underlying differences between QImage and QPixmap, so forgive my ignorance.
    Do you have any idea about how expensive the conversion from/to QPixmap
    actually is?


  • Lifetime Qt Champion

    It depends on the platform. On windows it's just a memcpy when the format of the image is Format_ARGB32_Premultiplied.


Log in to reply