Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsimagecache.h 3 : : --------------- 4 : : begin : December 2018 5 : : copyright : (C) 2018 by Nyall Dawson 6 : : email : nyall dot dawson at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #ifndef QGSIMAGECACHE_H 19 : : #define QGSIMAGECACHE_H 20 : : 21 : : #include "qgsabstractcontentcache.h" 22 : : #include "qgis_sip.h" 23 : : #include "qgis_core.h" 24 : : 25 : : #include <QElapsedTimer> 26 : : #include <QSize> 27 : : #include <QImage> 28 : : 29 : : #ifndef SIP_RUN 30 : : 31 : : ///@cond PRIVATE 32 : : 33 : : /** 34 : : * \ingroup core 35 : : * \class QgsImageCacheEntry 36 : : * \brief An entry for a QgsImageCache, representing a single raster rendered at a specific width and height. 37 : : * \since QGIS 3.6 38 : : */ 39 : 0 : class CORE_EXPORT QgsImageCacheEntry : public QgsAbstractContentCacheEntry 40 : : { 41 : : public: 42 : : 43 : : /** 44 : : * Constructor for QgsImageCacheEntry, corresponding to the specified image \a path , \a size and \a opacity. 45 : : * 46 : : * If \a keepAspectRatio is TRUE then the original raster aspect ratio will always be preserved 47 : : * when resizing. 48 : : */ 49 : : QgsImageCacheEntry( const QString &path, QSize size, bool keepAspectRatio, double opacity ) ; 50 : : 51 : : //! Rendered image size 52 : : QSize size; 53 : : 54 : : //! True if original raster aspect ratio was kept during resizing 55 : : bool keepAspectRatio = true; 56 : : 57 : : //! Rendered image opacity 58 : : double opacity = 1.0; 59 : : 60 : : //! Rendered, resampled image. 61 : : QImage image; 62 : : 63 : : /** 64 : : * TRUE if the image represents a broken/missing path. 65 : : * 66 : : * \since QGIS 3.14 67 : : */ 68 : : bool isMissingImage = false; 69 : : 70 : : int dataSize() const override; 71 : : void dump() const override; 72 : : bool isEqual( const QgsAbstractContentCacheEntry *other ) const override; 73 : : 74 : : }; 75 : : 76 : : ///@endcond 77 : : #endif 78 : : 79 : : /** 80 : : * \class QgsImageCache 81 : : * \ingroup core 82 : : * \brief A cache for images derived from raster files. 83 : : * 84 : : * QgsImageCache stores pre-rendered resampled versions of raster image files, allowing efficient 85 : : * reuse without incurring the cost of resampling on every render. 86 : : * 87 : : * QgsImageCache is not usually directly created, but rather accessed through 88 : : * QgsApplication::imageCache(). 89 : : * 90 : : * \since QGIS 3.6 91 : : */ 92 : : #ifdef SIP_RUN 93 : : class CORE_EXPORT QgsImageCache : public QgsAbstractContentCacheBase // for sip we skip to the base class and avoid the template difficulty 94 : : { 95 : : #else 96 : : class CORE_EXPORT QgsImageCache : public QgsAbstractContentCache< QgsImageCacheEntry > 97 : : { 98 : : #endif 99 : : Q_OBJECT 100 : : 101 : : public: 102 : : 103 : : /** 104 : : * Constructor for QgsImageCache, with the specified \a parent object. 105 : : */ 106 : : QgsImageCache( QObject *parent SIP_TRANSFERTHIS = nullptr ); 107 : : 108 : : /** 109 : : * Returns the specified \a path rendered as an image. If possible, a pre-existing cached 110 : : * version of the image will be used. If not, the image is fetched and resampled to the desired 111 : : * size, and then the result cached for subsequent lookups. 112 : : * 113 : : * \a path may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix). 114 : : * 115 : : * The \a size parameter dictates the target size of the image. An invalid size indicates the 116 : : * original raster image size (with no resampling). A size in which the width or height is 117 : : * set to zero will have the zeroed value automatically computed when keepAspectRatio is TRUE. 118 : : * 119 : : * If \a keepAspectRatio is TRUE, then the original raster aspect ratio will be maintained during 120 : : * any resampling operations. 121 : : * 122 : : * An \a opacity parameter dictates the opacity of the image. 123 : : * 124 : : * If the resultant raster was of a sufficiently small size to store in the cache, then \a fitsInCache 125 : : * will be set to TRUE. 126 : : * 127 : : * The \a blocking boolean forces to wait for loading before returning image. The content is loaded 128 : : * in the same thread to ensure provided the image. WARNING: the \a blocking parameter must NEVER 129 : : * be TRUE from GUI based applications (like the main QGIS application) or crashes will result. Only for 130 : : * use in external scripts or QGIS server. 131 : : */ 132 : : #ifndef SIP_RUN 133 : : QImage pathAsImage( const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache SIP_OUT, bool blocking = false, bool *isMissing = nullptr ); 134 : : #else 135 : : QImage pathAsImage( const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache SIP_OUT, bool blocking = false ); 136 : : #endif 137 : : 138 : : /** 139 : : * Returns the original size (in pixels) of the image at the specified \a path. 140 : : * 141 : : * \a path may be a local file, remote (HTTP) url, or a base 64 encoded string (with a "base64:" prefix). 142 : : * 143 : : * If \a path is a remote file, then an invalid size may be returned while the image is in the process 144 : : * of being fetched. 145 : : * 146 : : * The \a blocking boolean forces to wait for loading before returning the original size. The content is loaded 147 : : * in the same thread to ensure provided the original size. WARNING: the \a blocking parameter must NEVER 148 : : * be TRUE from GUI based applications (like the main QGIS application) or crashes will result. Only for 149 : : * use in external scripts or QGIS server. 150 : : * 151 : : * If the image could not be read then an invalid QSize is returned. 152 : : */ 153 : : QSize originalSize( const QString &path, bool blocking = false ) const; 154 : : 155 : : signals: 156 : : 157 : : /** 158 : : * Emitted when the cache has finished retrieving an image file from a remote \a url. 159 : : */ 160 : : void remoteImageFetched( const QString &url ); 161 : : 162 : : private: 163 : : 164 : : QImage renderImage( const QString &path, QSize size, const bool keepAspectRatio, const double opacity, bool &isBroken, bool blocking = false ) const; 165 : : 166 : : //! SVG content to be rendered if SVG file was not found. 167 : : QByteArray mMissingSvg; 168 : : 169 : : QByteArray mFetchingSvg; 170 : : 171 : : friend class TestQgsImageCache; 172 : : }; 173 : : 174 : : #endif // QGSIMAGECACHE_H