Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsimagecapture.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
8#include <private/qmediastoragelocation_p.h>
9
10#include <QtConcurrent/qtconcurrentrun.h>
11#include <QtGui/qimagewriter.h>
12
14
19
20QWindowsImageCapture::~QWindowsImageCapture() = default;
21
23{
24 if (!m_mediaDeviceSession)
25 return false;
26 return !m_capturing && m_mediaDeviceSession->isActive() && !m_mediaDeviceSession->activeCamera().isNull();
27}
28
29int QWindowsImageCapture::capture(const QString &fileName)
30{
31 auto ext = writerFormat(m_settings.format());
32 auto path = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, ext);
33 return doCapture(path);
34}
35
37{
38 return doCapture(QString());
39}
40
41int QWindowsImageCapture::doCapture(const QString &fileName)
42{
44 return -1;
45 m_fileName = fileName;
46 m_capturing = true;
47 return m_captureId;
48}
49
51{
52 return m_settings;
53}
54
55void QWindowsImageCapture::setImageSettings(const QImageEncoderSettings &settings)
56{
57 m_settings = settings;
58}
59
60void QWindowsImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session)
61{
62 QWindowsMediaCaptureService *captureService = static_cast<QWindowsMediaCaptureService *>(session);
63 if (m_captureService == captureService)
64 return;
65
66 auto readyForCapture = isReadyForCapture();
67 if (m_mediaDeviceSession)
68 disconnect(m_mediaDeviceSession, nullptr, this, nullptr);
69
70 m_captureService = captureService;
71 if (!m_captureService) {
72 if (readyForCapture)
73 emit readyForCaptureChanged(false);
74 m_mediaDeviceSession = nullptr;
75 return;
76 }
77
78 m_mediaDeviceSession = m_captureService->session();
79 Q_ASSERT(m_mediaDeviceSession);
80
81 if (isReadyForCapture() != readyForCapture)
82 emit readyForCaptureChanged(isReadyForCapture());
83
84 connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::readyForCaptureChanged,
85 this, &QWindowsImageCapture::readyForCaptureChanged);
86
87 connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::videoFrameChanged,
88 this, &QWindowsImageCapture::handleVideoFrameChanged);
89}
90
91void QWindowsImageCapture::handleVideoFrameChanged(const QVideoFrame &frame)
92{
93 if (m_capturing) {
94
95 QImage image = frame.toImage();
96
97 QSize size = m_settings.resolution();
98 if (size.isValid() && image.size() != size) {
99 image = image.scaled(size, Qt::KeepAspectRatioByExpanding);
100 if (image.size() != size) {
101 int xoff = (image.size().width() - size.width()) / 2;
102 int yoff = (image.size().height() - size.height()) / 2;
103 image = image.copy(xoff, yoff, size.width(), size.height());
104 }
105 }
106
107 emit imageExposed(m_captureId);
108 emit imageAvailable(m_captureId, frame);
109 emit imageCaptured(m_captureId, image);
110
111 QMediaMetaData metaData = this->metaData();
112 metaData.insert(QMediaMetaData::Date, QDateTime::currentDateTime());
113 metaData.insert(QMediaMetaData::Resolution, size);
114
115 emit imageMetadataAvailable(m_captureId, metaData);
116
117 if (!m_fileName.isEmpty()) {
118
119 (void)QtConcurrent::run(&QWindowsImageCapture::saveImage, this,
120 m_captureId, m_fileName, image, metaData, m_settings);
121 }
122
123 ++m_captureId;
124 m_capturing = false;
125 }
126}
127
128void QWindowsImageCapture::saveImage(int captureId, const QString &fileName,
129 const QImage &image, const QMediaMetaData &metaData,
130 const QImageEncoderSettings &settings)
131{
132 QImageWriter imageWriter;
133 imageWriter.setFileName(fileName);
134
135 QString format = writerFormat(settings.format());
136 imageWriter.setFormat(format.toUtf8());
137
138 int quality = writerQuality(format, settings.quality());
139 if (quality > -1)
140 imageWriter.setQuality(quality);
141
142 for (auto key : metaData.keys())
143 imageWriter.setText(QMediaMetaData::metaDataKeyToString(key),
144 metaData.stringValue(key));
145
146 imageWriter.write(image);
147
148 QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection,
149 Q_ARG(int, captureId), Q_ARG(QString, fileName));
150}
151
152QString QWindowsImageCapture::writerFormat(QImageCapture::FileFormat reqFormat)
153{
154 QString format;
155
156 switch (reqFormat) {
157 case QImageCapture::FileFormat::JPEG:
158 format = QLatin1String("jpg");
159 break;
160 case QImageCapture::FileFormat::PNG:
161 format = QLatin1String("png");
162 break;
163 case QImageCapture::FileFormat::WebP:
164 format = QLatin1String("webp");
165 break;
166 case QImageCapture::FileFormat::Tiff:
167 format = QLatin1String("tiff");
168 break;
169 default:
170 format = QLatin1String("jpg");
171 }
172
173 auto supported = QImageWriter::supportedImageFormats();
174 for (const auto &f : supported)
175 if (format.compare(QString::fromUtf8(f), Qt::CaseInsensitive) == 0)
176 return format;
177
178 return QLatin1String("jpg");
179}
180
181int QWindowsImageCapture::writerQuality(const QString &writerFormat,
182 QImageCapture::Quality quality)
183{
184 if (writerFormat.compare(QLatin1String("jpg"), Qt::CaseInsensitive) == 0 ||
185 writerFormat.compare(QLatin1String("jpeg"), Qt::CaseInsensitive) == 0) {
186
187 switch (quality) {
188 case QImageCapture::Quality::VeryLowQuality:
189 return 10;
190 case QImageCapture::Quality::LowQuality:
191 return 30;
192 case QImageCapture::Quality::NormalQuality:
193 return 75;
194 case QImageCapture::Quality::HighQuality:
195 return 90;
196 case QImageCapture::Quality::VeryHighQuality:
197 return 98;
198 default:
199 return 75;
200 }
201 }
202 return -1;
203}
204
205QT_END_NAMESPACE
206
207#include "moc_qwindowsimagecapture_p.cpp"
\inmodule QtMultimedia
QObject * parent
Definition qobject.h:73
int capture(const QString &fileName) override
QImageEncoderSettings imageSettings() const override
void setImageSettings(const QImageEncoderSettings &settings) override
bool isReadyForCapture() const override
QWindowsMediaDeviceSession * session() const
Combined button and popup list for selecting options.