1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickimageprovider.h"
46 class QQuickImageProviderPrivate
49 QQuickImageProvider::ImageType type;
50 QQuickImageProvider::Flags flags;
54 \class QQuickTextureFactory
56 \brief The QQuickTextureFactory class provides an interface for loading custom textures from QML.
59 The purpose of the texture factory is to provide a placeholder for a image
60 data that can be converted into an OpenGL texture.
62 Creating a texture directly is not possible as there is rarely an OpenGL context
63 available in the thread that is responsible for loading the image data.
67 Constructs a texture factory. Since QQuickTextureFactory is abstract, it
68 cannot be instantiated directly.
71 QQuickTextureFactory::QQuickTextureFactory()
76 Destroys the texture factory.
79 QQuickTextureFactory::~QQuickTextureFactory()
84 \fn int QQuickTextureFactory::textureByteCount() const
86 Returns the number of bytes of memory the texture consumes.
90 \fn QImage QQuickTextureFactory::image() const
92 Returns an image version of this texture.
94 The lifespan of the returned image is unknown, so the implementation should
95 return a self contained QImage, not make use of the QImage(uchar *, ...)
98 This function is not commonly used and is expected to be slow.
101 QImage QQuickTextureFactory::image() const
108 \fn QSGTexture *QQuickTextureFactory::createTexture(QQuickWindow *window) const
110 This function is called on the scene graph rendering thread to create a QSGTexture
111 instance from the factory. \a window provides the context which this texture is
114 QML will internally cache the returned texture as needed. Each call to this
115 function should return a unique instance.
117 The OpenGL context used for rendering is bound when this function is called.
121 \fn QSize QQuickTextureFactory::textureSize() const
123 Returns the size of the texture. This function will be called from arbitrary threads
124 and should not rely on an OpenGL context bound.
129 \class QQuickImageProvider
132 \brief The QQuickImageProvider class provides an interface for supporting pixmaps and threaded image requests in QML.
134 QQuickImageProvider is used to provide advanced image loading features
135 in QML applications. It allows images in QML to be:
138 \li Loaded using QPixmaps rather than actual image files
139 \li Loaded asynchronously in a separate thread, if imageType() is \l{QQuickImageProvider::ImageType}{ImageType::Image}
142 To specify that an image should be loaded by an image provider, use the
143 \b {"image:"} scheme for the URL source of the image, followed by the
144 identifiers of the image provider and the requested image. For example:
147 Image { source: "image://myimageprovider/image.png" }
150 This specifies that the image should be loaded by the image provider named
151 "myimageprovider", and the image to be loaded is named "image.png". The QML engine
152 invokes the appropriate image provider according to the providers that have
153 been registered through QQmlEngine::addImageProvider().
155 Note that the identifiers are case-insensitive, but the rest of the URL will be passed on with
156 preserved case. For example, the below snippet would still specify that the image is loaded by the
157 image provider named "myimageprovider", but it would request a different image than the above snippet
158 ("Image.png" instead of "image.png").
160 Image { source: "image://MyImageProvider/Image.png" }
163 If you want the rest of the URL to be case insensitive, you will have to take care
164 of that yourself inside your image provider.
168 Here are two images. Their \c source values indicate they should be loaded by
169 an image provider named "colors", and the images to be loaded are "yellow"
170 and "red", respectively:
172 \snippet examples/qml/imageprovider/imageprovider-example.qml 0
174 When these images are loaded by QML, it looks for a matching image provider
175 and calls its requestImage() or requestPixmap() method (depending on its
176 imageType()) to load the image. The method is called with the \c id
177 parameter set to "yellow" for the first image, and "red" for the second.
179 Here is an image provider implementation that can load the images
180 requested by the above QML. This implementation dynamically
181 generates QPixmap images that are filled with the requested color:
183 \snippet examples/qml/imageprovider/imageprovider.cpp 0
185 \snippet examples/qml/imageprovider/imageprovider.cpp 1
187 To make this provider accessible to QML, it is registered with the QML engine
188 with a "colors" identifier:
191 int main(int argc, char *argv[])
196 engine->addImageProvider(QLatin1String("colors"), new ColorPixmapProvider);
202 Now the images can be successfully loaded in QML:
204 \image imageprovider.png
206 A complete example is available in Qt's
207 \l {qml/imageprovider}{examples/qml/imageprovider}
208 directory. Note the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
209 instead of registering it in the application \c main() function as shown above.
212 \section2 Asynchronous image loading
214 Image providers that support QImage loading automatically include support
215 for asychronous loading of images. To enable asynchronous loading for an
216 image source, set the \c asynchronous property to \c true for the relevant
217 \l Image, \l BorderImage or \l AnimatedImage object. When this is enabled,
218 the image request to the provider is run in a low priority thread,
219 allowing image loading to be executed in the background, and reducing the
220 performance impact on the user interface.
222 To force asynchronous image loading, even for image sources that do not
223 have the \c asynchronous property set to \c true, you may pass the
224 \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
225 provider constructor. This ensures that all image requests for the
226 provider are handled in a separate thread.
228 Asynchronous loading is not supported for image providers that provide
229 QPixmap rather than QImage values, as pixmaps can only be created in the
230 main thread. In this case, if \l {Image::}{asynchronous} is set to
231 \c true, the value is ignored and the image is loaded
235 \section2 Image caching
237 Images returned by a QQuickImageProvider are automatically cached,
238 similar to any image loaded by the QML engine. When an image with a
239 "image://" prefix is loaded from cache, requestImage() and requestPixmap()
240 will not be called for the relevant image provider. If an image should always
241 be fetched from the image provider, and should not be cached at all, set the
242 \c cache property to \c false for the relevant \l Image, \l BorderImage or
243 \l AnimatedImage object.
245 The QtQuick 1 version of this class is named QDeclarativeImageProvider.
247 \sa QQmlEngine::addImageProvider()
251 Creates an image provider that will provide images of the given \a type and
252 behave according to the given \a flags.
254 QQuickImageProvider::QQuickImageProvider(ImageType type, Flags flags)
255 : d(new QQuickImageProviderPrivate)
262 Destroys the QQuickImageProvider
264 \note The destructor of your derived class need to be thread safe.
266 QQuickImageProvider::~QQuickImageProvider()
272 Returns the image type supported by this provider.
274 QQuickImageProvider::ImageType QQuickImageProvider::imageType() const
280 Returns the flags set for this provider.
282 QQuickImageProvider::Flags QQuickImageProvider::flags() const
288 Implement this method to return the image with \a id. The default
289 implementation returns an empty image.
291 The \a id is the requested image source, with the "image:" scheme and
292 provider identifier removed. For example, if the image \l{Image::}{source}
293 was "image://myprovider/icons/home", the given \a id would be "icons/home".
295 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
296 an Image item. If \a requestedSize is a valid size, the image
297 returned should be of that size.
299 In all cases, \a size must be set to the original size of the image. This
300 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
301 relevant \l Image if these values have not been set explicitly.
303 \note this method may be called by multiple threads, so ensure the
304 implementation of this method is reentrant.
306 QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const QSize& requestedSize)
310 Q_UNUSED(requestedSize);
311 if (d->type == Image)
312 qWarning("ImageProvider supports Image type but has not implemented requestImage()");
317 Implement this method to return the pixmap with \a id. The default
318 implementation returns an empty pixmap.
320 The \a id is the requested image source, with the "image:" scheme and
321 provider identifier removed. For example, if the image \l{Image::}{source}
322 was "image://myprovider/icons/home", the given \a id would be "icons/home".
324 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
325 an Image item. If \a requestedSize is a valid size, the image
326 returned should be of that size.
328 In all cases, \a size must be set to the original size of the image. This
329 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
330 relevant \l Image if these values have not been set explicitly.
332 QPixmap QQuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
336 Q_UNUSED(requestedSize);
337 if (d->type == Pixmap)
338 qWarning("ImageProvider supports Pixmap type but has not implemented requestPixmap()");
344 Implement this method to return the texture with \a id. The default
345 implementation returns 0.
347 The \a id is the requested image source, with the "image:" scheme and
348 provider identifier removed. For example, if the image \l{Image::}{source}
349 was "image://myprovider/icons/home", the given \a id would be "icons/home".
351 The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
352 an Image item. If \a requestedSize is a valid size, the image
353 returned should be of that size.
355 In all cases, \a size must be set to the original size of the image. This
356 is used to set the \l {Item::}{width} and \l {Item::}{height} of the
357 relevant \l Image if these values have not been set explicitly.
359 \note this method may be called by multiple threads, so ensure the
360 implementation of this method is reentrant.
363 QQuickTextureFactory *QQuickImageProvider::requestTexture(const QString &id, QSize *size, const QSize &requestedSize)
367 Q_UNUSED(requestedSize);
368 if (d->type == Texture)
369 qWarning("ImageProvider supports Texture type but has not implemented requestTexture()");