diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index be2a54b8e9..1a65c5e8d7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6935,10 +6935,10 @@ void Application::loadAvatarBrowser() const { DependencyManager::get()->openTablet(); } -void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { - postLambdaEvent([notify, includeAnimated, aspectRatio, this] { +void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { + postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] { // Get a screenshot and save it - QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); + QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename); // If we're not doing an animated snapshot as well... if (!includeAnimated) { // Tell the dependency manager that the capture of the still snapshot has taken place. @@ -6950,9 +6950,9 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa }); } -void Application::takeSecondaryCameraSnapshot() { - postLambdaEvent([this] { - QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot()); +void Application::takeSecondaryCameraSnapshot(const QString& filename) { + postLambdaEvent([filename, this] { + QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename); emit DependencyManager::get()->stillSnapshotTaken(snapshotPath, true); }); } diff --git a/interface/src/Application.h b/interface/src/Application.h index ddb8ce11e5..33f784a07f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -266,8 +266,10 @@ public: float getGameLoopRate() const { return _gameLoopCounter.rate(); } - void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f); - void takeSecondaryCameraSnapshot(); + // Note that takeSnapshot has a default value, as this method is used internally. + void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f, const QString& filename = QString()); + void takeSecondaryCameraSnapshot(const QString& filename); + void shareSnapshot(const QString& filename, const QUrl& href = QUrl("")); graphics::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 8a7743a849..3a3d313fb4 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -430,12 +430,12 @@ bool WindowScriptingInterface::setDisplayTexture(const QString& name) { return qApp->getActiveDisplayPlugin()->setDisplayTexture(name); // Plugins that don't know how, answer false. } -void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { - qApp->takeSnapshot(notify, includeAnimated, aspectRatio); +void WindowScriptingInterface::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) { + qApp->takeSnapshot(notify, includeAnimated, aspectRatio, filename); } -void WindowScriptingInterface::takeSecondaryCameraSnapshot() { - qApp->takeSecondaryCameraSnapshot(); +void WindowScriptingInterface::takeSecondaryCameraSnapshot(const QString& filename) { + qApp->takeSecondaryCameraSnapshot(filename); } void WindowScriptingInterface::shareSnapshot(const QString& path, const QUrl& href) { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index dc71611c5b..76decf4362 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -334,6 +334,8 @@ public slots: * @param {number} aspectRatio=0 - The width/height ratio of the snapshot required. If the value is 0 the * full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the * dimensions is adjusted in order to match the aspect ratio. + * @param {string} filename=QString() - If this value is not null then the image will be saved to this filename, with an appended ",jpg". + * otherwise, the image will be saved as 'hifi-snap-by--YYYY-MM-DD_HH-MM-SS' * @example Using the snapshot function and signals. * function onStillSnapshotTaken(path, notify) { * print("Still snapshot taken: " + path); @@ -355,15 +357,19 @@ public slots: * var notify = true; * var animated = true; * var aspect = 1920 / 1080; - * Window.takeSnapshot(notify, animated, aspect); + * var filename = QString(); + * Window.takeSnapshot(notify, animated, aspect, filename); */ - void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f); + void takeSnapshot(bool notify = true, bool includeAnimated = false, float aspectRatio = 0.0f, const QString& filename = QString()); /**jsdoc * Takes a still snapshot of the current view from the secondary camera that can be set up through the {@link Render} API. * @function Window.takeSecondaryCameraSnapshot + * @param {string} filename=QString() - If this value is not null then the image will be saved to this filename, with an appended ".jpg" + * + * var filename = QString(); */ - void takeSecondaryCameraSnapshot(); + void takeSecondaryCameraSnapshot(const QString& filename = QString()); /**jsdoc * Emit a {@link Window.connectionAdded|connectionAdded} or a {@link Window.connectionError|connectionError} signal that diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 59ecce5bc7..9b3089d78d 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -73,9 +73,9 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } -QString Snapshot::saveSnapshot(QImage image) { +QString Snapshot::saveSnapshot(QImage image, const QString& filename) { - QFile* snapshotFile = savedFileForSnapshot(image, false); + QFile* snapshotFile = savedFileForSnapshot(image, false, filename); // we don't need the snapshot file, so close it, grab its filename and delete it snapshotFile->close(); @@ -92,7 +92,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { return static_cast(savedFileForSnapshot(image, true)); } -QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) { +QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename) { // adding URL to snapshot QUrl currentURL = DependencyManager::get()->currentShareableAddress(); @@ -104,7 +104,15 @@ QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary) { QDateTime now = QDateTime::currentDateTime(); - QString filename = FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT)); + // If user has requested specific filename then use it, else create the filename + // 'jpg" is appended, as the image is saved in jpg format. This is the case for all snapshots + // (see definition of FILENAME_PATH_FORMAT) + QString filename; + if (!userSelectedFilename.isNull()) { + filename = userSelectedFilename + ".jpg"; + } else { + filename = FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT)); + } const int IMAGE_QUALITY = 100; diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 1246e1d004..62d3ed3db8 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -37,7 +37,7 @@ class Snapshot : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY public: - static QString saveSnapshot(QImage image); + static QString saveSnapshot(QImage image, const QString& filename); static QTemporaryFile* saveTempSnapshot(QImage image); static SnapshotMetaData* parseSnapshotData(QString snapshotPath); @@ -51,7 +51,7 @@ public slots: Q_INVOKABLE QString getSnapshotsLocation(); Q_INVOKABLE void setSnapshotsLocation(const QString& location); private: - static QFile* savedFileForSnapshot(QImage & image, bool isTemporary); + static QFile* savedFileForSnapshot(QImage & image, bool isTemporary, const QString& userSelectedFilename = QString()); }; #endif // hifi_Snapshot_h