How to show QImage from http url?
-
Hey, I would like to cache images from an url and show them from local file system, but if file doesn't exists then I would need to download it from url. Any advices how I should proceed?
I found this class:
QDeclarativeImageProvider, where I can return Image from Qt side and there I can do something like this:@QImage requestImage(const QString &id;, QSize *size, const QSize &requestedSize;)
{QDir dir; QFile file( dir.absolutePath() + "images/" + id + ".jpg" ); if (file.exists()) { QImage img; img.load(dir.absolutePath() + "images/" + id + ".jpg"); return img; } else { Load from url }
}@
How to do that load from url part.
I found this example: http://www.qtcentre.org/threads/1483-Qt4-How-to-load-Url-image-into-QImage
But how can I return the image, when it's created in slot?Thanks for any tips.
-
You can also use custom "QDeclarativeNetworkAccessManagerFactory":http://doc.qt.nokia.com/4.7/qdeclarativenetworkaccessmanagerfactory.html to cache images with cache-enabled QNAM.
-
[quote author="Denis Kormalev" date="1311023033"]You can also use custom "QDeclarativeNetworkAccessManagerFactory":http://doc.qt.nokia.com/4.7/qdeclarativenetworkaccessmanagerfactory.html to cache images with cache-enabled QNAM.[/quote]
That sounds even trickier task
-
[quote author="Chuck Gao" date="1311063146"]If so, i think the key point is the file path(local or internet). QML Image element's source can be a url, so you just need to get the file path. The element itself will take care of the http part.[/quote]
Yes, I know. but I don't want to download it from the internet everytime, but make a local copy and then take it from there if exists.
-
You want cache the images yourself ? I mean, store them into the cache and get them from the cache. I'm not sure if the QML Image element use caching when load url image. But you can try QNetworkDiskCache. I found this in the document: "Images are cached and shared internally, so if several Image elements have the same source, only one copy of the image will be loaded". Let's look into the source code. :-)
-
Yes, I would like to cache by myself :) I don't think that the QML caches those automatically since it always takes so long to get the images to the screen.
Maybe need to investigate that QNetworkDiscCache, but I wouldn't mind if someone could give me a solution to problem I had in the main question :)
-
I have a look at the source code, and QML will cache those images for you, with
@
QDeclarativeImageBase::load()
{
...
QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url;, const QSize &requestSize;, bool async)
{
if (d) { d->release(); d = 0; }QDeclarativePixmapKey key = { &url;, &requestSize; }; QDeclarativePixmapStore *store = pixmapStore(); QHash<QDeclarativePixmapKey, QDeclarativePixmapData *>::Iterator iter = store->m_cache.find(key); if (iter == store->m_cache.end()) { if (async) { // pixmaps can only be loaded synchronously if (url.scheme() == QLatin1String("image") && QDeclarativeEnginePrivate::get(engine)->getImageProviderType(url) == QDeclarativeImageProvider::Pixmap) { async = false; } } if (!async) { bool ok = false; d = createPixmapDataSync(engine, url, requestSize, &ok;); if (ok) { d->addToCache(); return; } if (d) // loadable, but encountered error while loading return; } if (!engine) return; QDeclarativePixmapReader *reader = QDeclarativePixmapReader::instance(engine); d = new QDeclarativePixmapData(url, requestSize); d->addToCache(); d->reply = reader->getImage(d); } else { d = *iter; d->addref(); }
}
.....
}
@ -
[quote author="jkosonen" date="1311064731"]Yes, I would like to cache by myself :) I don't think that the QML caches those automatically since it always takes so long to get the images to the screen.
Maybe need to investigate that QNetworkDiscCache, but I wouldn't mind if someone could give me a solution to problem I had in the main question :)[/quote]
QNetworkDiskCache is the same way I've suggested. It is really not hard (maybe a 5 or 10 lines of code)
-
[quote author="Denis Kormalev" date="1311065955"][quote author="jkosonen" date="1311064731"]Yes, I would like to cache by myself :) I don't think that the QML caches those automatically since it always takes so long to get the images to the screen.
Maybe need to investigate that QNetworkDiscCache, but I wouldn't mind if someone could give me a solution to problem I had in the main question :)[/quote]
QNetworkDiskCache is the same way I've suggested. It is really not hard (maybe a 5 or 10 lines of code)[/quote]
Can you point me to any site with example, with QML?
-
"example about QDeclarativeNetworkAccessManagerFactory":http://doc.qt.nokia.com/4.7/declarative-cppextensions-networkaccessmanagerfactory.html
"QNetworkDiskCache":http://doc.qt.nokia.com/4.7/qnetworkdiskcache.html (there is an example of how to use it with QNAM) -
[quote author="Denis Kormalev" date="1311066630"]"example about QDeclarativeNetworkAccessManagerFactory":http://doc.qt.nokia.com/4.7/declarative-cppextensions-networkaccessmanagerfactory.html
"QNetworkDiskCache":http://doc.qt.nokia.com/4.7/qnetworkdiskcache.html (there is an example of how to use it with QNAM)[/quote]Thanks, will try that!
but there is this:
When sending requests, to control the preference of when to use the cache and when to use the network, consider the following:
@ // do a normal request (preferred from network, as this is the default)
QNetworkRequest request(QUrl(QString("http://qt.nokia.com")));
manager->get(request);// do a request preferred from cache
QNetworkRequest request2(QUrl(QString("http://qt.nokia.com")));
request2.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
manager->get(request2);@How do I say in QML to prfer cache?
-
jkosonen, it will prefer a cache in most part of cases (if we are talking about images)
-
[quote author="Denis Kormalev" date="1311067186"]jkosonen, it will prefer a cache in most part of cases (if we are talking about images)[/quote]
OK, but how to say then not to use cache, or clear cache?
Cache isn't always preferred, would be nice to know when it is used and when it's not. -
jkosonen, clearing cache is possbile with simple removing all contents of cache dir. I'm not aware of any other ways.