on xenial help sign in
Try to use QImageReader not to load the image into memory twice
commitee61f43bb26ec65242664fbc57843bd8052b1f89 authorAlbert Astals <albert.astals@canonical.com> dateFri 24 Oct 2014, 09:04 (12 years ago) parent1ff2631
8 files changed+245−23
plugins/Dash/CMakeLists.txt+1 plugins/Dash/CardCreator.js+6−5 plugins/Dash/CroppedImageMinimumSourceSize.qml+24−18 plugins/Dash/croppedimagesizer.cpp+115 plugins/Dash/croppedimagesizer.h+67 plugins/Dash/plugin.cpp+2 tests/plugins/Dash/CMakeLists.txt+2 tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qml+28
plugins/Dash/CMakeLists.txt+1
@@ -25,6 +25,7 @@ set(QMLPLUGIN_SRC
2525 verticaljournal.cpp
2626 horizontaljournal.cpp
2727 organicgrid.cpp
28+ croppedimagesizer.cpp
2829 )
2930
3031add_library(Dash-qml MODULE
plugins/Dash/CardCreator.js+6−5
@@ -82,16 +82,17 @@ var kArtShapeHolderCode = 'Item { \n\
8282 height = Qt.binding(function() { return image.status !== Image.Ready ? 0 : image.height }); \n\
8383 } \n\
8484 } \n\
85− image: CroppedImageMinimumSourceSize { \n\
85+ CroppedImageMinimumSourceSize { \n\
86+ id: artImage; \n\
8687 objectName: "artImage"; \n\
8788 property bool doLoadSource: !NetworkingStatus.limitedBandwith; \n\
8889 source: { if (root.visible) doLoadSource = true; return doLoadSource && cardData && cardData["art"] || ""; } \n\
89− cache: true; \n\
9090 asynchronous: root.asynchronous; \n\
9191 visible: false; \n\
9292 width: %2; \n\
9393 height: %3; \n\
9494 } \n\
95+ image: artImage.image; \n\
9596 } \n\
9697 } \n\
9798 }\n';
@@ -181,11 +182,11 @@ var kMascotShapeLoaderCode = 'Loader { \n\
181182 id: mascotShapeLoader; \n\
182183 objectName: "mascotShapeLoader"; \n\
183184 asynchronous: root.asynchronous; \n\
184− active: mascotImage.status === Image.Ready; \n\
185+ active: mascotImage.image.status === Image.Ready; \n\
185186 visible: showHeader && active && status == Loader.Ready; \n\
186187 width: units.gu(6); \n\
187188 height: units.gu(5.625); \n\
188− sourceComponent: UbuntuShape { image: mascotImage } \n\
189+ sourceComponent: UbuntuShape { image: mascotImage.image } \n\
189190 anchors { %1 } \n\
190191 }\n';
191192
@@ -433,7 +434,7 @@ function cardString(template, components) {
433434 mascotShapeCode = kMascotShapeLoaderCode.arg(mascotAnchors);
434435 }
435436
436− var mascotImageVisible = useMascotShape ? 'false' : 'showHeader && resized';
437+ var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
437438 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
438439 }
439440
plugins/Dash/CroppedImageMinimumSourceSize.qml+24−18
@@ -15,24 +15,30 @@
1515 */
1616
1717import QtQuick 2.3
18+import Dash 0.1
1819
19−Image {
20− property bool resized: false
21− property bool resizing: false
22− fillMode: Image.PreserveAspectCrop
23− visible: resized
24− onSourceSizeChanged: {
25− if (!resized && !resizing) {
26− resizing = true;
27− var ar = width / height;
28− var ssar = sourceSize.width / sourceSize.height;
29− if (ar > ssar) {
30− sourceSize = Qt.size(width, 0);
31− } else {
32− sourceSize = Qt.size(0, height);
33− }
34− resizing = false;
35− resized = true;
36− }
20+Item {
21+ id: root
22+
23+ property alias image: image
24+ property string source
25+ property alias asynchronous: image.asynchronous
26+ property alias verticalAlignment: image.verticalAlignment
27+ property alias horizontalAlignment: image.horizontalAlignment
28+
29+ CroppedImageSizer
30+ {
31+ id: sizer
32+ source: root.source
33+ width: root.width
34+ height: root.height
35+ }
36+
37+ Image {
38+ id: image
39+ anchors.fill: parent
40+ fillMode: Image.PreserveAspectCrop
41+ sourceSize: sizer.sourceSize.width == 0 && sizer.sourceSize.height == 0 ? undefined : sizer.sourceSize
42+ source: sourceSize.width == -1 && sourceSize.height == -1 ? "" : root.source
3743 }
3844}
plugins/Dash/croppedimagesizer.cppnew file+115
@@ -0,0 +1,115 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "croppedimagesizer.h"
18+
19+#include <QDebug>
20+#include <QNetworkReply>
21+#include <QNetworkRequest>
22+#include <QQmlEngine>
23+#include <QQuickItem>
24+#include <QQuickView>
25+
26+CroppedImageSizer::CroppedImageSizer()
27+{
28+ connect(this, &CroppedImageSizer::inputParamsChanged, this, &CroppedImageSizer::calculateSourceSize);
29+}
30+
31+CroppedImageSizer::~CroppedImageSizer()
32+{
33+ if (m_reply) {
34+ m_reply->deleteLater();
35+ }
36+}
37+
38+QUrl CroppedImageSizer::source() const
39+{
40+ return m_source;
41+}
42+
43+void CroppedImageSizer::setSource(const QUrl &source)
44+{
45+ if (source != m_source) {
46+ m_source = source;
47+ Q_EMIT inputParamsChanged();
48+ }
49+}
50+
51+qreal CroppedImageSizer::width() const
52+{
53+ return m_width;
54+}
55+
56+void CroppedImageSizer::setWidth(qreal width)
57+{
58+ if (width != m_width) {
59+ m_width = width;
60+ Q_EMIT inputParamsChanged();
61+ }
62+}
63+
64+qreal CroppedImageSizer::height() const
65+{
66+ return m_height;
67+}
68+
69+void CroppedImageSizer::setHeight(qreal height)
70+{
71+ if (height != m_height) {
72+ m_height = height;
73+ Q_EMIT inputParamsChanged();
74+ }
75+}
76+
77+QSize CroppedImageSizer::sourceSize() const
78+{
79+ return m_sourceSize;
80+}
81+
82+void CroppedImageSizer::calculateSourceSize()
83+{
84+ if (m_source.isValid() && m_width > 0 && m_height > 0 && qmlEngine(this) && qmlEngine(this)->networkAccessManager()) {
85+ if (m_reply) {
86+ m_reply->abort();
87+ m_reply->deleteLater();
88+ }
89+ QNetworkRequest request(m_source);
90+ m_reply = qmlEngine(this)->networkAccessManager()->get(request);
91+ connect(m_reply, &QNetworkReply::finished, this, &CroppedImageSizer::requestFinished);
92+ }
93+}
94+
95+void CroppedImageSizer::requestFinished()
96+{
97+ QImageReader m_reader(m_reply);
98+ const QSize imageSize = m_reader.size();
99+ if (imageSize.isValid()) {
100+ const qreal ar = width() / height();
101+ const qreal ssar = imageSize.width() / imageSize.height();
102+ if (ar > ssar) {
103+ m_sourceSize = QSize(m_width, 0);
104+ } else {
105+ m_sourceSize = QSize(0, m_height);
106+ }
107+ } else {
108+ qWarning() << "Could not find size of" << m_source;
109+ m_sourceSize = QSize(0, 0);
110+ }
111+ sourceSizeChanged();
112+
113+ m_reply->deleteLater();
114+ m_reply = nullptr;
115+}
plugins/Dash/croppedimagesizer.hnew file+67
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#ifndef CROPPEDIMAGESIZER_H
18+#define CROPPEDIMAGESIZER_H
19+
20+#include <QImageReader>
21+#include <QObject>
22+#include <QSize>
23+#include <QUrl>
24+
25+class QNetworkReply;
26+
27+class CroppedImageSizer : public QObject
28+{
29+ Q_OBJECT
30+
31+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY inputParamsChanged)
32+ Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY inputParamsChanged)
33+ Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY inputParamsChanged)
34+ Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
35+
36+public:
37+ CroppedImageSizer();
38+ ~CroppedImageSizer();
39+
40+ QUrl source() const;
41+ void setSource(const QUrl &source);
42+
43+ qreal width() const;
44+ void setWidth(qreal width);
45+
46+ qreal height() const;
47+ void setHeight(qreal height);
48+
49+ QSize sourceSize() const;
50+
51+Q_SIGNALS:
52+ void inputParamsChanged();
53+ void sourceSizeChanged();
54+
55+private Q_SLOT:
56+ void calculateSourceSize();
57+ void requestFinished();
58+
59+private:
60+ QUrl m_source;
61+ qreal m_width = 0;
62+ qreal m_height = 0;
63+ QSize m_sourceSize = QSize(-1, -1);
64+ QNetworkReply *m_reply = nullptr;
65+};
66+
67+#endif
plugins/Dash/plugin.cpp+2
@@ -17,6 +17,7 @@
1717
1818#include "plugin.h"
1919
20+#include "croppedimagesizer.h"
2021#include "horizontaljournal.h"
2122#include "listviewwithpageheader.h"
2223#include "organicgrid.h"
@@ -32,4 +33,5 @@ void DashPlugin::registerTypes(const char *uri)
3233 qmlRegisterType<ListViewWithPageHeader>(uri, 0, 1, "ListViewWithPageHeader");
3334 qmlRegisterType<OrganicGrid>(uri, 0, 1, "OrganicGrid");
3435 qmlRegisterType<VerticalJournal>(uri, 0, 1, "VerticalJournal");
36+ qmlRegisterType<CroppedImageSizer>(uri, 0, 1, "CroppedImageSizer");
3537}
tests/plugins/Dash/CMakeLists.txt+2
@@ -73,6 +73,8 @@ qt5_use_modules(CardCreatorTestExec Test Core Qml)
7373target_link_libraries(CardCreatorTestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
7474add_binary_qml_test(CardCreator "" "Dash-qml" "QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks/")
7575
76+add_qml_test(. CroppedImageMinimumSourceSize IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
77+
7678# plain qml test
7779set(qmltest_DEFAULT_TARGETS qmluitests)
7880set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
tests/plugins/Dash/tst_CroppedImageMinimumSourceSize.qmlnew file+28
@@ -0,0 +1,28 @@
1+
2+import QtQuick 2.3
3+import Ubuntu.Components 1.1
4+import Dash 0.1
5+
6+Rectangle {
7+ width: 500
8+ height: 300
9+
10+ color: "red"
11+
12+ CroppedImageMinimumSourceSize {
13+ x: 100
14+ y: 100
15+ width: 100
16+ height: 100
17+ source: Qt.resolvedUrl("../../qmltests/Dash/artwork/avatar.png")
18+ }
19+
20+ CroppedImageMinimumSourceSize {
21+ x: 300
22+ y: 100
23+ width: 100
24+ height: 100
25+ source: "http://assets.ubuntu.com/sites/ubuntu/latest/u/img/homepage/1410/1410-wallpaper.jpg"
26+ }
27+}
28+