aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Belyavsky <belyavskyv@gmail.com>2022-12-10 18:20:46 +0300
committerVladimir Belyavsky <belyavskyv@gmail.com>2023-01-26 08:20:00 +0000
commit5c496ad9527487a0d9d33ac0882fab439c993b02 (patch)
tree47c836cf7d75e785e44904b0e6a466d26c91bedb
parent5bcbd0a513dcf929890a869ad01c68b3175fa6e2 (diff)
AnimatedImage: Add ability to configure sourceSize
This allows to reduce memory consumption and improve performance when you need to load and play hi-res GIF files or animated SVG. [ChangeLog][QtQuick][AnimatedImage] It's now possible to configure sourceSize property for AnimatedImage. This might be useful when you need e.g. to play hi-res GIF files in some smaller size. Fixes: QTBUG-57501 Change-Id: I26d464855bbc20e155a8fb589a48842986a3dea4 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/quick/items/qquickanimatedimage.cpp64
-rw-r--r--src/quick/items/qquickanimatedimage_p.h3
-rw-r--r--src/quick/items/qquickanimatedimage_p_p.h3
-rw-r--r--tests/auto/quick/qquickanimatedimage/data/stickmansourcesized.qml (renamed from tests/auto/quick/qquickanimatedimage/data/stickmanerror1.qml)2
-rw-r--r--tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp17
5 files changed, 46 insertions, 43 deletions
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index d40a440d94..7d08782aab 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -26,8 +26,10 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine
QUrl requestedUrl;
QQuickPixmap *pixmap = nullptr;
if (engine && !movie->fileName().isEmpty()) {
- requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2")
+ requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2x%3#%4")
.arg(movie->fileName())
+ .arg(movie->scaledSize().width())
+ .arg(movie->scaledSize().height())
.arg(current));
}
if (!requestedUrl.isEmpty()) {
@@ -289,14 +291,14 @@ void QQuickAnimatedImage::load()
}
d->setImage(QImage());
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
+
d->status = Null;
emit statusChanged(d->status);
- d->currentSourceSize = QSize(0, 0);
- if (d->currentSourceSize != d->oldSourceSize) {
- d->oldSourceSize = d->currentSourceSize;
- emit sourceSizeChanged();
- }
if (isPlaying() != d->oldPlaying)
emit playingChanged();
} else {
@@ -337,7 +339,6 @@ void QQuickAnimatedImage::load()
void QQuickAnimatedImage::movieRequestFinished()
{
-
Q_D(QQuickAnimatedImage);
#if QT_CONFIG(qml_network)
@@ -363,19 +364,21 @@ void QQuickAnimatedImage::movieRequestFinished()
qmlWarning(this) << "Error Reading Animated Image File "
<< (context ? context->resolvedUrl(d->url) : d->url).toString();
d->setMovie(nullptr);
+
d->setImage(QImage());
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
+
if (d->progress != 0) {
d->progress = 0;
emit progressChanged(d->progress);
}
+
d->status = Error;
emit statusChanged(d->status);
- d->currentSourceSize = QSize(0, 0);
- if (d->currentSourceSize != d->oldSourceSize) {
- d->oldSourceSize = d->currentSourceSize;
- emit sourceSizeChanged();
- }
if (isPlaying() != d->oldPlaying)
emit playingChanged();
return;
@@ -387,9 +390,6 @@ void QQuickAnimatedImage::movieRequestFinished()
d->movie->setCacheMode(QMovie::CacheAll);
d->movie->setSpeed(qRound(d->speed * 100.0));
- d->status = Ready;
- emit statusChanged(d->status);
-
if (d->progress != 1.0) {
d->progress = 1.0;
emit progressChanged(d->progress);
@@ -406,21 +406,19 @@ void QQuickAnimatedImage::movieRequestFinished()
}
QQuickPixmap *pixmap = d->infoForCurrentFrame(qmlEngine(this));
- if (pixmap)
+ if (pixmap) {
d->setPixmap(*pixmap);
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
+ }
+
+ d->status = Ready;
+ emit statusChanged(d->status);
if (isPlaying() != d->oldPlaying)
emit playingChanged();
-
- if (d->movie)
- d->currentSourceSize = d->movie->currentPixmap().size();
- else
- d->currentSourceSize = QSize(0, 0);
-
- if (d->currentSourceSize != d->oldSourceSize) {
- d->oldSourceSize = d->currentSourceSize;
- emit sourceSizeChanged();
- }
}
void QQuickAnimatedImage::movieUpdate()
@@ -466,12 +464,6 @@ void QQuickAnimatedImage::onCacheChanged()
}
}
-QSize QQuickAnimatedImage::sourceSize()
-{
- Q_D(QQuickAnimatedImage);
- return d->currentSourceSize;
-}
-
void QQuickAnimatedImage::componentComplete()
{
QQuickItem::componentComplete(); // NOT QQuickImage
@@ -482,6 +474,7 @@ void QQuickAnimatedImagePrivate::setMovie(QMovie *m)
{
if (movie == m)
return;
+
Q_Q(QQuickAnimatedImage);
const int oldFrameCount = q->frameCount();
@@ -489,8 +482,15 @@ void QQuickAnimatedImagePrivate::setMovie(QMovie *m)
movie->disconnect();
movie->deleteLater();
}
+
movie = m;
+ qDeleteAll(frameMap);
+ frameMap.clear();
+
+ if (movie)
+ movie->setScaledSize(sourcesize);
+
if (oldFrameCount != q->frameCount())
emit q->frameCountChanged();
}
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index b8af3e1e40..38beb6d1c3 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -36,8 +36,6 @@ class Q_QUICK_PRIVATE_EXPORT QQuickAnimatedImage : public QQuickImage
Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION(2, 11))
- // read-only for AnimatedImage
- Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
QML_NAMED_ELEMENT(AnimatedImage)
QML_ADDED_IN_VERSION(2, 0)
@@ -61,7 +59,6 @@ public:
// Extends QQuickImage's src property
void setSource(const QUrl&) override;
- virtual QSize sourceSize();
Q_SIGNALS:
void playingChanged();
diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h
index 8e2ee8a82d..341ac3bc02 100644
--- a/src/quick/items/qquickanimatedimage_p_p.h
+++ b/src/quick/items/qquickanimatedimage_p_p.h
@@ -35,7 +35,7 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate
public:
QQuickAnimatedImagePrivate()
: playing(true), paused(false), oldPlaying(false), padding(0)
- , presetCurrentFrame(0), speed(1.0), currentSourceSize(0, 0), movie(nullptr)
+ , presetCurrentFrame(0), speed(1.0), movie(nullptr)
#if QT_CONFIG(qml_network)
, reply(nullptr), redirectCount(0)
#endif
@@ -51,7 +51,6 @@ public:
unsigned padding: 29;
int presetCurrentFrame;
qreal speed;
- QSize currentSourceSize;
QMovie *movie;
#if QT_CONFIG(qml_network)
QNetworkReply *reply;
diff --git a/tests/auto/quick/qquickanimatedimage/data/stickmanerror1.qml b/tests/auto/quick/qquickanimatedimage/data/stickmansourcesized.qml
index 4f823b3d70..76d277df62 100644
--- a/tests/auto/quick/qquickanimatedimage/data/stickmanerror1.qml
+++ b/tests/auto/quick/qquickanimatedimage/data/stickmansourcesized.qml
@@ -1,6 +1,6 @@
import QtQuick 2.0
AnimatedImage {
- sourceSize: "240x180"
+ sourceSize: "80x60"
source: "stickman.gif"
}
diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
index 1a01a8aca5..cb81ec8a07 100644
--- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
+++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
@@ -52,9 +52,9 @@ private slots:
void remote();
void remote_data();
void sourceSize();
+ void setSourceSize();
void sourceSizeChanges();
void sourceSizeChanges_intermediate();
- void sourceSizeReadOnly();
void invalidSource();
void qtbug_16520();
void progressAndStatusChanges();
@@ -287,12 +287,19 @@ void tst_qquickanimatedimage::sourceSize()
delete anim;
}
-void tst_qquickanimatedimage::sourceSizeReadOnly()
+void tst_qquickanimatedimage::setSourceSize()
{
QQmlEngine engine;
- QQmlComponent component(&engine, testFileUrl("stickmanerror1.qml"));
- QVERIFY(component.isError());
- QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
+ QQmlComponent component(&engine, testFileUrl("stickmansourcesized.qml"));
+ QScopedPointer<QQuickAnimatedImage> anim(qobject_cast<QQuickAnimatedImage *>(component.create()));
+ QVERIFY(anim);
+ QCOMPARE(anim->sourceSize(), QSize(80, 60));
+
+ anim->setSourceSize(QSize(40, 30));
+ QCOMPARE(anim->sourceSize(), QSize(40, 30));
+
+ anim->setSourceSize(QSize());
+ QCOMPARE(anim->sourceSize(), QSize(160, 120));
}
void tst_qquickanimatedimage::invalidSource()