74 using namespace Qt::Literals::StringLiterals;
79 QMetaObject::invokeMethod(
84 QImageCapture::ResourceError,
85 QPlatformImageCapture::msgImageCaptureNotSet());
93 QMetaObject::invokeMethod(
98 QImageCapture::ResourceError,
99 u"No camera available."_s);
104 if (m_pendingImages.size() >= MaxPendingImagesCount) {
107 QMetaObject::invokeMethod(
112 QImageCapture::NotReadyError,
113 QPlatformImageCapture::msgCameraNotReady());
120 m_pendingImages.enqueue({ m_lastId, fileName, QMediaMetaData{} });
128 auto *captureSession =
static_cast<QFFmpegMediaCaptureSession *>(session);
129 if (m_session == captureSession)
133 m_session->disconnect(
this);
135 m_pendingImages.clear();
138 m_session = captureSession;
141 connect(m_session, &QFFmpegMediaCaptureSession::primaryActiveVideoSourceChanged,
this,
143 connect(m_session, &QFFmpegMediaCaptureSession::cameraChanged,
this,
155 if (m_pendingImages.empty()) {
157 "QImageCapture backend received an event to cancel a pending capture, "
158 "but no captures are pending. Most likely an internal Qt bug.";
162 PendingImage cancelledImage = m_pendingImages.dequeue();
164 Q_EMIT QPlatformImageCapture::error(cancelledImage.id, error, errorMsg);
166 updateReadyForCapture();
182 if (m_pendingImages.empty())
185 auto pending = m_pendingImages.dequeue();
187 qCDebug(qLcImageCapture) <<
"Taking image" << pending.id;
189 Q_EMIT imageExposed(pending.id);
191 Q_EMIT imageMetadataAvailable(pending.id, pending.metaData);
192 Q_EMIT imageAvailable(pending.id, frame);
193 QImage image = frame.toImage();
195 const QSize resolution = m_settings.resolution();
196 const bool isRotated = image.width() != image.height()
197 && resolution.width() != resolution.height()
198 && (image.width() > image.height()) != (resolution.width() > resolution.height());
199 const QSize targetSize = isRotated ? resolution.transposed() : resolution;
200 if (targetSize.isValid() && image.size() != targetSize) {
202 <<
"Image needed to be scaled to match requested resolution (" << image.size()
203 <<
" -> " << targetSize
204 <<
", consider using a resolution supported natively by the camera";
205 image = image.scaled(targetSize);
208 Q_EMIT imageCaptured(pending.id, image);
209 if (!pending.filename.isEmpty()) {
210 const char *fmt =
nullptr;
211 switch (m_settings.format()) {
212 case QImageCapture::UnspecifiedFormat:
213 case QImageCapture::JPEG:
216 case QImageCapture::PNG:
219 case QImageCapture::WebP:
222 case QImageCapture::Tiff:
227 switch (m_settings.quality()) {
228 case QImageCapture::VeryLowQuality:
231 case QImageCapture::LowQuality:
234 case QImageCapture::NormalQuality:
236 case QImageCapture::HighQuality:
239 case QImageCapture::VeryHighQuality:
244 QImageWriter writer(pending.filename, fmt);
245 writer.setQuality(quality);
247 if (writer.write(image)) {
248 Q_EMIT imageSaved(pending.id, pending.filename);
250 QImageCapture::Error err = QImageCapture::ResourceError;
251 if (writer.error() == QImageWriter::UnsupportedFormatError)
252 err = QImageCapture::FormatError;
253 Q_EMIT error(pending.id, err, writer.errorString());
295 const auto supportedFormats = QPlatformMediaIntegration::instance()->formatInfo()->imageFormats;
296 if (supportedFormats.isEmpty()) {
297 Q_EMIT error(-1, QImageCapture::FormatError, u"No image formats supported, can't capture."_s);
300 if (s.format() == QImageCapture::UnspecifiedFormat) {
301 auto f = QImageCapture::JPEG;
302 if (!supportedFormats.contains(f))
303 f = supportedFormats.first();
305 }
else if (!supportedFormats.contains(settings.format())) {
306 Q_EMIT error(-1, QImageCapture::FormatError, u"Image format not supported."_s);
310 m_settings = settings;