27 #include <QApplication>
28 #include <QCoreApplication>
30 #include <QDomDocument>
31 #include <QDomElement>
37 #include <QNetworkReply>
38 #include <QNetworkRequest>
40 #include <QImageReader>
41 #include <QSvgRenderer>
45 QgsImageCacheEntry::QgsImageCacheEntry(
const QString &path, QSize size,
const bool keepAspectRatio,
const double opacity )
48 , keepAspectRatio( keepAspectRatio )
55 const QgsImageCacheEntry *otherImage =
dynamic_cast< const QgsImageCacheEntry *
>( other );
57 if ( !otherImage || otherImage->keepAspectRatio != keepAspectRatio || otherImage->size != size || otherImage->path != path || otherImage->opacity != opacity )
63 int QgsImageCacheEntry::dataSize()
const
66 if ( !image.isNull() )
68 size += ( image.width() * image.height() * 32 );
73 void QgsImageCacheEntry::dump()
const
75 QgsDebugMsgLevel( QStringLiteral(
"path: %1, size %2x%3" ).arg( path ).arg( size.width() ).arg( size.height() ), 3 );
84 mMissingSvg = QStringLiteral(
"<svg width='10' height='10'><text x='5' y='10' font-size='10' text-anchor='middle'>?</text></svg>" ).toLatin1();
87 if ( QFile::exists( downloadingSvgPath ) )
89 QFile file( downloadingSvgPath );
90 if ( file.open( QIODevice::ReadOnly ) )
92 mFetchingSvg = file.readAll();
96 if ( mFetchingSvg.isEmpty() )
98 mFetchingSvg = QStringLiteral(
"<svg width='10' height='10'><text x='5' y='10' font-size='10' text-anchor='middle'>?</text></svg>" ).toLatin1();
104 QImage
QgsImageCache::pathAsImage(
const QString &f,
const QSize size,
const bool keepAspectRatio,
const double opacity,
bool &fitsInCache,
bool blocking,
bool *isMissing )
106 const QString file = f.trimmed();
110 if ( file.isEmpty() )
113 QMutexLocker locker( &
mMutex );
117 QgsImageCacheEntry *currentEntry =
findExistingEntry(
new QgsImageCacheEntry( file, size, keepAspectRatio, opacity ) );
124 if ( currentEntry->image.isNull() )
126 long cachedDataSize = 0;
127 bool isBroken =
false;
128 result = renderImage( file, size, keepAspectRatio, opacity, isBroken, blocking );
129 cachedDataSize += result.width() * result.height() * 32;
133 currentEntry->image = QImage();
137 mTotalSize += ( result.width() * result.height() * 32 );
138 currentEntry->image = result;
142 *isMissing = isBroken;
143 currentEntry->isMissingImage = isBroken;
149 result = currentEntry->image;
151 *isMissing = currentEntry->isMissingImage;
159 if ( path.isEmpty() )
163 if ( !path.startsWith( QStringLiteral(
"base64:" ) ) && QFile::exists( path ) )
165 QImageReader reader( path );
166 if ( reader.size().isValid() )
167 return reader.size();
169 return QImage( path ).size();
173 QByteArray ba =
getContent( path, QByteArray(
"broken" ), QByteArray(
"fetching" ), blocking );
175 if ( ba !=
"broken" && ba !=
"fetching" )
177 QBuffer buffer( &ba );
178 buffer.open( QIODevice::ReadOnly );
180 QImageReader reader( &buffer );
183 const QSize s = reader.size();
186 QImage im = reader.read();
187 return im.isNull() ? QSize() : im.size();
193 QImage QgsImageCache::renderImage(
const QString &path, QSize size,
const bool keepAspectRatio,
const double opacity,
bool &isBroken,
bool blocking )
const
199 if ( !path.startsWith( QStringLiteral(
"base64:" ) ) && QFile::exists( path ) )
205 QByteArray ba =
getContent( path, QByteArray(
"broken" ), QByteArray(
"fetching" ), blocking );
207 if ( ba ==
"broken" )
212 if ( !size.isValid() )
216 if ( size.width() == 0 )
217 size.setWidth( size.height() );
218 if ( size.height() == 0 )
219 size.setHeight( size.width() );
221 im = QImage( size, QImage::Format_ARGB32_Premultiplied );
225 QSvgRenderer r( mMissingSvg );
227 QSizeF s( r.viewBox().size() );
228 s.scale( size.width(), size.height(), Qt::KeepAspectRatio );
229 QRectF rect( ( size.width() - s.width() ) / 2, ( size.height() - s.height() ) / 2, s.width(), s.height() );
230 r.render( &p, rect );
232 else if ( ba ==
"fetching" )
235 if ( size.width() == 0 )
236 size.setWidth( size.height() );
237 if ( size.height() == 0 )
238 size.setHeight( size.width() );
241 im = QImage( size, QImage::Format_ARGB32_Premultiplied );
245 QSvgRenderer r( mFetchingSvg );
247 QSizeF s( r.viewBox().size() );
248 s.scale( size.width(), size.height(), Qt::KeepAspectRatio );
249 QRectF rect( ( size.width() - s.width() ) / 2, ( size.height() - s.height() ) / 2, s.width(), s.height() );
250 r.render( &p, rect );
254 QBuffer buffer( &ba );
255 buffer.open( QIODevice::ReadOnly );
257 QImageReader reader( &buffer );
262 if ( !im.hasAlphaChannel() )
263 im = im.convertToFormat( QImage::Format_ARGB32 );
269 if ( !size.isValid() || size.isNull() || im.size() == size )
272 else if ( keepAspectRatio && size.height() == 0 )
273 return im.scaledToWidth( size.width(), Qt::SmoothTransformation );
275 else if ( keepAspectRatio && size.width() == 0 )
276 return im.scaledToHeight( size.height(), Qt::SmoothTransformation );
278 return im.scaled( size, keepAspectRatio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio, Qt::SmoothTransformation );