1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the plugins of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qdeclarativecamera_p.h"
41#include "qdeclarativecameracapture_p.h"
42#include "qdeclarativecamerapreviewprovider_p.h"
43
44#include <qmetadatawritercontrol.h>
45
46#include <QtCore/qurl.h>
47
48QT_BEGIN_NAMESPACE
49
50/*!
51 \qmltype CameraCapture
52 \instantiates QDeclarativeCameraCapture
53 \brief An interface for capturing camera images.
54 \ingroup multimedia_qml
55 \inqmlmodule QtMultimedia
56 \ingroup camera_qml
57
58 This type allows you to capture still images and be notified when they
59 are available or saved to disk. You can adjust the resolution of the captured
60 image and where the saved image should go.
61
62 CameraCapture is a child of a \l Camera (as the \c imageCapture property)
63 and cannot be created directly.
64
65 \qml
66 Item {
67 width: 640
68 height: 360
69
70 Camera {
71 id: camera
72
73 imageCapture {
74 onImageCaptured: {
75 // Show the preview in an Image
76 photoPreview.source = preview
77 }
78 }
79 }
80
81 VideoOutput {
82 source: camera
83 focus : visible // to receive focus and capture key events when visible
84 anchors.fill: parent
85
86 MouseArea {
87 anchors.fill: parent;
88 onClicked: camera.imageCapture.capture();
89 }
90 }
91
92 Image {
93 id: photoPreview
94 }
95 }
96 \endqml
97
98*/
99
100QDeclarativeCameraCapture::QDeclarativeCameraCapture(QCamera *camera, QObject *parent) :
101 QObject(parent),
102 m_camera(camera)
103{
104 m_capture = new QCameraImageCapture(camera, this);
105
106 connect(sender: m_capture, SIGNAL(readyForCaptureChanged(bool)), receiver: this, SIGNAL(readyForCaptureChanged(bool)));
107 connect(sender: m_capture, SIGNAL(imageExposed(int)), receiver: this, SIGNAL(imageExposed(int)));
108 connect(sender: m_capture, SIGNAL(imageCaptured(int,QImage)), receiver: this, SLOT(_q_imageCaptured(int,QImage)));
109 connect(sender: m_capture, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), receiver: this,
110 SLOT(_q_imageMetadataAvailable(int,QString,QVariant)));
111 connect(sender: m_capture, SIGNAL(imageSaved(int,QString)), receiver: this, SLOT(_q_imageSaved(int,QString)));
112 connect(sender: m_capture, SIGNAL(error(int,QCameraImageCapture::Error,QString)),
113 receiver: this, SLOT(_q_captureFailed(int,QCameraImageCapture::Error,QString)));
114
115 connect(sender: m_camera, SIGNAL(statusChanged(QCamera::Status)),
116 receiver: this, SLOT(_q_cameraStatusChanged(QCamera::Status)));
117
118 QMediaService *service = camera->service();
119 m_metadataWriterControl = service ? service->requestControl<QMetaDataWriterControl*>() : 0;
120}
121
122QDeclarativeCameraCapture::~QDeclarativeCameraCapture()
123{
124}
125
126/*!
127 \property QDeclarativeCameraCapture::ready
128
129 This property holds a bool value indicating whether the camera
130 is ready to capture photos or not.
131
132 Calling capture() while \e ready is \c false is not permitted and
133 results in an error.
134*/
135
136/*!
137 \qmlproperty bool QtMultimedia::CameraCapture::ready
138
139 This property holds a bool value indicating whether the camera
140 is ready to capture photos or not.
141
142 Calling capture() while \e ready is \c false is not permitted and
143 results in an error.
144*/
145bool QDeclarativeCameraCapture::isReadyForCapture() const
146{
147 return m_capture->isReadyForCapture();
148}
149
150/*!
151 \qmlmethod QtMultimedia::CameraCapture::capture()
152
153 Start image capture. The \l imageCaptured and \l imageSaved signals will
154 be emitted when the capture is complete.
155
156 The image will be captured to the default system location, typically
157 QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) for
158 still imaged or QStandardPaths::writableLocation(QStandardPaths::MoviesLocation)
159 for video.
160
161 Camera saves all the capture parameters like exposure settings or
162 image processing parameters, so changes to camera parameters after
163 capture() is called do not affect previous capture requests.
164
165 capture() returns the capture requestId parameter, used with
166 imageExposed(), imageCaptured(), imageMetadataAvailable() and imageSaved() signals.
167
168 \sa ready
169*/
170int QDeclarativeCameraCapture::capture()
171{
172 return m_capture->capture();
173}
174
175/*!
176 \qmlmethod QtMultimedia::CameraCapture::captureToLocation(location)
177
178 Start image capture to specified \a location. The \l imageCaptured and \l imageSaved signals will
179 be emitted when the capture is complete.
180
181 CameraCapture::captureToLocation returns the capture requestId parameter, used with
182 imageExposed(), imageCaptured(), imageMetadataAvailable() and imageSaved() signals.
183
184 If the application is unable to write to the location specified by \c location
185 the CameraCapture will emit an error. The most likely reasons for the application
186 to be unable to write to a location is that the path is wrong and the location does not exists,
187 or the application does not have write permission for that location.
188*/
189int QDeclarativeCameraCapture::captureToLocation(const QString &location)
190{
191 return m_capture->capture(location);
192}
193
194/*!
195 \qmlmethod QtMultimedia::CameraCapture::cancelCapture()
196
197 Cancel pending image capture requests.
198*/
199
200void QDeclarativeCameraCapture::cancelCapture()
201{
202 m_capture->cancelCapture();
203}
204/*!
205 \property QDeclarativeCameraCapture::capturedImagePath
206
207 This property holds the location of the last captured image.
208*/
209/*!
210 \qmlproperty string QtMultimedia::CameraCapture::capturedImagePath
211
212 This property holds the location of the last captured image.
213*/
214QString QDeclarativeCameraCapture::capturedImagePath() const
215{
216 return m_capturedImagePath;
217}
218
219void QDeclarativeCameraCapture::_q_imageCaptured(int id, const QImage &preview)
220{
221 QString previewId = QString("preview_%1").arg(a: id);
222 QDeclarativeCameraPreviewProvider::registerPreview(id: previewId, preview);
223
224 emit imageCaptured(requestId: id, preview: QLatin1String("image://camera/")+previewId);
225}
226
227void QDeclarativeCameraCapture::_q_imageSaved(int id, const QString &fileName)
228{
229 m_capturedImagePath = fileName;
230 emit imageSaved(requestId: id, path: fileName);
231}
232
233void QDeclarativeCameraCapture::_q_imageMetadataAvailable(int id, const QString &key, const QVariant &value)
234{
235 emit imageMetadataAvailable(requestId: id, key, value);
236}
237
238
239void QDeclarativeCameraCapture::_q_captureFailed(int id, QCameraImageCapture::Error error, const QString &message)
240{
241 Q_UNUSED(error);
242 qWarning() << "QCameraImageCapture error:" << message;
243 emit captureFailed(requestId: id, message);
244}
245
246void QDeclarativeCameraCapture::_q_cameraStatusChanged(QCamera::Status status)
247{
248 if (status != QCamera::UnloadedStatus && status != QCamera::LoadedStatus &&
249 status != QCamera::ActiveStatus)
250 return;
251
252 emit supportedResolutionsChanged();
253}
254/*!
255 \property QDeclarativeCameraCapture::resolution
256
257 This property holds the resolution/size of the image to be captured.
258 If empty, the system chooses the appropriate resolution.
259*/
260
261/*!
262 \qmlproperty size QtMultimedia::CameraCapture::resolution
263
264 This property holds the resolution/size of the image to be captured.
265 If empty, the system chooses the appropriate resolution.
266
267 \sa supportedResolutions
268*/
269
270QSize QDeclarativeCameraCapture::resolution()
271{
272 return m_imageSettings.resolution();
273}
274
275void QDeclarativeCameraCapture::setResolution(const QSize &captureResolution)
276{
277 m_imageSettings = m_capture->encodingSettings();
278 if (captureResolution != resolution()) {
279 m_imageSettings.setResolution(captureResolution);
280 m_capture->setEncodingSettings(m_imageSettings);
281 emit resolutionChanged(captureResolution);
282 }
283}
284
285QCameraImageCapture::Error QDeclarativeCameraCapture::error() const
286{
287 return m_capture->error();
288}
289/*!
290 \property QDeclarativeCameraCapture::errorString
291
292 This property holds the error message related to the last capture.
293*/
294
295/*!
296 \qmlproperty string QtMultimedia::CameraCapture::errorString
297
298 This property holds the error message related to the last capture.
299*/
300QString QDeclarativeCameraCapture::errorString() const
301{
302 return m_capture->errorString();
303}
304
305/*!
306 \qmlproperty list<size> QtMultimedia::CameraCapture::supportedResolutions
307
308 This property holds a list of resolutions which are supported for capturing.
309 The information can be used to set a valid \e resolution. If the camera isn't
310 loaded, the list will be empty.
311
312 \since 5.9
313 \sa resolution
314 */
315QVariantList QDeclarativeCameraCapture::supportedResolutions()
316{
317 QVariantList supportedResolutions;
318 for (const QSize &res : m_capture->supportedResolutions())
319 supportedResolutions.append(t: QVariant(res));
320 return supportedResolutions;
321}
322
323/*!
324 \qmlmethod QtMultimedia::CameraCapture::setMetadata(key, value)
325
326
327 Sets a particular metadata \a key to \a value for the subsequent image captures.
328
329 \sa QMediaMetaData
330*/
331void QDeclarativeCameraCapture::setMetadata(const QString &key, const QVariant &value)
332{
333 if (m_metadataWriterControl)
334 m_metadataWriterControl->setMetaData(key, value);
335}
336
337/*!
338 \qmlsignal QtMultimedia::CameraCapture::captureFailed(requestId, message)
339
340 This signal is emitted when an error occurs during capture with \a requestId.
341 A descriptive message is available in \a message.
342
343 The corresponding handler is \c onCaptureFailed.
344*/
345
346/*!
347 \qmlsignal QtMultimedia::CameraCapture::imageCaptured(requestId, preview)
348
349 This signal is emitted when an image with \a requestId has been captured
350 but not yet saved to the filesystem. The \a preview
351 parameter can be used as the URL supplied to an \l Image.
352
353 The corresponding handler is \c onImageCaptured.
354
355 \sa imageSaved
356*/
357
358/*!
359 \qmlsignal QtMultimedia::CameraCapture::imageSaved(requestId, path)
360
361 This signal is emitted after the image with \a requestId has been written to the filesystem.
362 The \a path is a local file path, not a URL.
363
364 The corresponding handler is \c onImageSaved.
365
366 \sa imageCaptured
367*/
368
369
370/*!
371 \qmlsignal QtMultimedia::CameraCapture::imageMetadataAvailable(requestId, key, value)
372
373 This signal is emitted when the image with \a requestId has new metadata
374 available with the key \a key and value \a value.
375
376 The corresponding handler is \c onImageMetadataAvailable.
377
378 \sa imageCaptured
379*/
380
381
382QT_END_NAMESPACE
383
384#include "moc_qdeclarativecameracapture_p.cpp"
385

source code of qtmultimedia/src/imports/multimedia/qdeclarativecameracapture.cpp