diff --git a/tablet_qt/questionnairelib/quphoto.cpp b/tablet_qt/questionnairelib/quphoto.cpp index 108d92288..78b5fa6f2 100644 --- a/tablet_qt/questionnairelib/quphoto.cpp +++ b/tablet_qt/questionnairelib/quphoto.cpp @@ -246,8 +246,6 @@ void QuPhoto::takePhoto() qDebug() << "... CameraQml() created"; #endif connect(m_camera, &CameraQml::cancelled, this, &QuPhoto::cameraCancelled); - connect(m_camera, &CameraQml::rawImageCaptured, - this, &QuPhoto::rawImageCaptured); connect(m_camera, &CameraQml::imageCaptured, this, &QuPhoto::imageCaptured); @@ -333,43 +331,6 @@ void QuPhoto::imageCaptured(const QImage& image) } -void QuPhoto::rawImageCaptured(const QByteArray& data, - const QString& extension_without_dot, - const QString& mimetype) -{ -#ifdef DEBUG_CAMERA - qDebug() << Q_FUNC_INFO; -#endif - if (!m_camera) { - qWarning() << Q_FUNC_INFO << "... no camera!"; - return; - } - if (!m_questionnaire) { - qWarning() << Q_FUNC_INFO << "... no questionnaire!"; - return; - } - bool changed = false; - { // guard block - SlowGuiGuard guard = m_questionnaire->app().getSlowGuiGuard( - tr("Saving image..."), - tr("Saving")); -#ifdef DEBUG_CAMERA - qDebug() << "QuPhoto: setting field value to raw image..."; -#endif - changed = m_fieldref->setRawImage(data, - extension_without_dot, - mimetype); -#ifdef DEBUG_CAMERA - qDebug() << "QuPhoto: ... field value set to raw image."; -#endif - m_camera->finish(); // close the camera - } - if (changed) { - emit elementValueChanged(); - } -} - - void QuPhoto::rotate(const int angle_degrees_clockwise) { if (m_fieldref->isNull()) { diff --git a/tablet_qt/questionnairelib/quphoto.h b/tablet_qt/questionnairelib/quphoto.h index 3a6c302b1..1a574aac5 100644 --- a/tablet_qt/questionnairelib/quphoto.h +++ b/tablet_qt/questionnairelib/quphoto.h @@ -72,11 +72,6 @@ protected slots: // "User cancelled taking a photo." void cameraCancelled(); - // "Camera sends you this captured raw image." - void rawImageCaptured(const QByteArray& data, - const QString& extension_without_dot, - const QString& mimetype); - // "Camera sends you this captured QImage." void imageCaptured(const QImage& image); diff --git a/tablet_qt/resources/camcops/camera_qml/PhotoPreview.qml b/tablet_qt/resources/camcops/camera_qml/PhotoPreview.qml index de5d7b4dd..71f586f07 100644 --- a/tablet_qt/resources/camcops/camera_qml/PhotoPreview.qml +++ b/tablet_qt/resources/camcops/camera_qml/PhotoPreview.qml @@ -57,7 +57,7 @@ import QtMultimedia Item { signal closed - signal imageSavedToFile // RNC + signal previewSaved // RNC Image { // http://doc.qt.io/qt-6.2/qml-qtquick-image.html id: preview @@ -85,7 +85,7 @@ Item { text: qsTr("Save") onClicked: { console.log("Save button clicked") - imageSavedToFile() + previewSaved() } } } diff --git a/tablet_qt/resources/camcops/camera_qml/camera.qml b/tablet_qt/resources/camcops/camera_qml/camera.qml index d8805e76d..b63f9e643 100644 --- a/tablet_qt/resources/camcops/camera_qml/camera.qml +++ b/tablet_qt/resources/camcops/camera_qml/camera.qml @@ -58,7 +58,8 @@ import QtMultimedia Rectangle { id : cameraUI - signal imageSavedToFile(string filename) // RNC + signal imageCaptured(variant previewImage) + signal previewSaved signal fileNoLongerNeeded(string filename) // RNC width: 800 @@ -139,8 +140,8 @@ Rectangle { console.log("Image captured") stillControls.previewAvailable = true cameraUI.state = "PhotoPreview" + cameraUI.imageCaptured(previewImage) } - // RNC: onImageSaved: function(requestId, path) { console.log("onImageSaved: ", path) stillControls.fileSaved = true @@ -160,9 +161,9 @@ Rectangle { onClosed: cameraUI.state = "PhotoCapture" visible: (cameraUI.state === "PhotoPreview") focus: visible - onImageSavedToFile: { - console.log("Returning image with filename:", stillControls.filePath) - cameraUI.imageSavedToFile(stillControls.filePath) + onPreviewSaved: { + cameraUI.previewSaved() + cameraUI.fileNoLongerNeeded(stillControls.filePath) } } diff --git a/tablet_qt/widgets/cameraqml.cpp b/tablet_qt/widgets/cameraqml.cpp index db25149e8..cf5fbd0e5 100644 --- a/tablet_qt/widgets/cameraqml.cpp +++ b/tablet_qt/widgets/cameraqml.cpp @@ -166,8 +166,9 @@ void CameraQml::qmlFinishedLoading() Q_ASSERT(root); // It's possible to connect to non-root objects, but it's much cleaner to // route from QML child objects up to the QML root object, and then to C++. - connect(root, SIGNAL(imageSavedToFile(const QString&)), - this, SLOT(cameraHasCapturedImage(const QString&))); + connect(root, SIGNAL(imageCaptured(const QVariant&)), + this, SLOT(copyPreviewImage(const QVariant&))); + connect(root, SIGNAL(previewSaved()), this, SLOT(savePreviewImage())); connect(root, SIGNAL(fileNoLongerNeeded(const QString&)), this, SLOT(deleteSuperfluousFile(const QString&))); // ... we have to use SIGNAL() and SLOT() since C++ has no idea of the @@ -178,6 +179,18 @@ void CameraQml::qmlFinishedLoading() } +void CameraQml::copyPreviewImage(const QVariant& preview) +{ + m_preview = preview.value(); +} + + +void CameraQml::savePreviewImage() +{ + emit imageCaptured(m_preview); +} + + void CameraQml::deleteFile(const QString& filename) const { #ifdef DEBUG_CAMERA @@ -198,50 +211,3 @@ void CameraQml::deleteSuperfluousFile(const QString& filename) const #endif deleteFile(filename); } - - -void CameraQml::cameraHasCapturedImage(const QString& filename) -{ -#ifdef DEBUG_CAMERA - qDebug() << Q_FUNC_INFO; - qDebug() << "Camera image has arrived via temporary file" << filename; -#endif - - const QFileInfo fileinfo(filename); - const QString extension_without_dot = fileinfo.suffix(); - const QMimeDatabase mime_db; - const QMimeType mime_type = mime_db.mimeTypeForFile(filename); - // ... default method is to use filename and contents - // ... it will ALWAYS BE VALID, but may be "application/octet-stream" if - // Qt doesn't know what it is: - // http://doc.qt.io/qt-5/qmimedatabase.html#mimeTypeForFile - const QString mimetype_name = mime_type.name(); - - QFile file(filename); - if (mimetype_name != "application/octet-stream" && - file.open(QIODevice::ReadOnly)) { - - // We know the MIME type (and can read the file), so we can use the - // higher-performance method. - const QByteArray data = file.readAll(); - file.close(); - deleteFile(filename); -#ifdef DEBUG_CAMERA - qDebug() << "Camera image data loaded"; -#endif - emit rawImageCaptured(data, extension_without_dot, mimetype_name); - - } else { - -#ifdef DEBUG_CAMERA - qDebug() << "Camera image loaded"; -#endif - QImage img; - img.load(filename); - deleteFile(filename); - emit imageCaptured(img); - - } - - close(); -} diff --git a/tablet_qt/widgets/cameraqml.h b/tablet_qt/widgets/cameraqml.h index 5ac44f4c9..74b742fc8 100644 --- a/tablet_qt/widgets/cameraqml.h +++ b/tablet_qt/widgets/cameraqml.h @@ -86,16 +86,6 @@ class CameraQml : public OpenableWidget void finish(); signals: - // If possible, we will emit rawImageCaptured, because performance is - // better. Failing that, we will emit imageCaptured. ONE OR THE OTHER will - // be emitted. - - // "We've captured an image." High performance. - void rawImageCaptured(QByteArray data, // QByteArray is copy-on-write - QString extension_without_dot, - QString mimetype); - - // "We've captured an image." Lower performance. void imageCaptured(QImage image); // QImage is copy-on-write // "User has cancelled the operation." @@ -124,14 +114,14 @@ protected slots: // Called from m_qml_view's QQuickWidget::statusChanged. void qmlStatusChanged(QQuickWidget::Status status); + void copyPreviewImage(const QVariant& preview); + void savePreviewImage(); // "The camera QML says a temporary file is no longer needed." // Called from the fileNoLongerNeeded signal defined in camera.qml. void deleteSuperfluousFile(const QString& filename) const; - // "The camera QML has captured an image via a temporary file." - // Called from the imageSavedToFile signal defined in camera.qml. - void cameraHasCapturedImage(const QString& filename); - protected: QPointer m_qml_view; // our QML view widget +private: + QImage m_preview; };