[libcamera-devel,RFC/PATCH,4/5] qcam: Remove QFileDialog from JPEG capture

Message ID 20200430003604.2423018-5-niklas.soderlund@ragnatech.se
State Superseded
Headers show
Series
  • qcam: Add RAW capture support
Related show

Commit Message

Niklas Söderlund April 30, 2020, 12:36 a.m. UTC
Instead of popping up a dialog to enter a filename to save use the
sequence number and the default output directory to generate a path.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 src/qcam/main_window.cpp | 40 +++++++++++++++++++++++++++-------------
 src/qcam/main_window.h   |  3 ++-
 2 files changed, 29 insertions(+), 14 deletions(-)

Comments

Laurent Pinchart April 30, 2020, 7:34 p.m. UTC | #1
Hi Niklas,

Thank you for the patch.

On Thu, Apr 30, 2020 at 02:36:03AM +0200, Niklas Söderlund wrote:
> Instead of popping up a dialog to enter a filename to save use the
> sequence number and the default output directory to generate a path.

I think we should keep the current save option and add a quick save for
this.

> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> ---
>  src/qcam/main_window.cpp | 40 +++++++++++++++++++++++++++-------------
>  src/qcam/main_window.h   |  3 ++-
>  2 files changed, 29 insertions(+), 14 deletions(-)
> 
> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
> index 470f78162cabffe5..f57aaf4a27e5f4ca 100644
> --- a/src/qcam/main_window.cpp
> +++ b/src/qcam/main_window.cpp
> @@ -8,6 +8,7 @@
>  #include "main_window.h"
>  
>  #include <iomanip>
> +#include <sstream>
>  #include <string>
>  #include <sys/mman.h>
>  
> @@ -146,8 +147,7 @@ int MainWindow::createToolbars()
>  	action = toolbar_->addAction(QIcon::fromTheme("document-save-as",
>  						      QIcon(":save.svg")),
>  				     "Save As...");
> -	action->setShortcut(QKeySequence::SaveAs);
> -	connect(action, &QAction::triggered, this, &MainWindow::saveImageAs);
> +	connect(action, &QAction::triggered, this, &MainWindow::saveViewfinder);
>  
>  	return 0;
>  }
> @@ -509,18 +509,9 @@ void MainWindow::stopCapture()
>   * Image Save
>   */
>  
> -void MainWindow::saveImageAs()
> +void MainWindow::saveViewfinder()
>  {
> -	QImage image = viewfinder_->getCurrentImage();
> -
> -	QString filename = QFileDialog::getSaveFileName(this, "Save Image", defaultPath_,
> -							"Image Files (*.png *.jpg *.jpeg)");
> -	if (filename.isEmpty())
> -		return;
> -
> -	QImageWriter writer(filename);
> -	writer.setQuality(95);
> -	writer.write(image);
> +	saveViewfinder_ = true;

You'll need to set saveViewFinder_ to false in stopCapture() I think.
There could also be other concurrent operations that I haven't thought
about.

>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -602,6 +593,29 @@ void MainWindow::processViewfinder(FrameBuffer *buffer)
>  
>  	/* Render the frame on the viewfinder. */
>  	viewfinder_->render(buffer, &mappedBuffers_[buffer]);
> +
> +	/* Save viewfinder to file if requested. */
> +	if (saveViewfinder_) {
> +		std::string filename = defaultPath_.toStdString() + "/picture-#.jpeg";

s/jpeg/jpg/

Note that Qt can also save to other formats, such as PNG. Removing the
file save dialog we're losing this capability.

> +		size_t pos;
> +
> +		pos = filename.find_first_of('#');
> +		if (pos != std::string::npos) {
> +			std::stringstream ss;
> +			ss << std::setw(6) << std::setfill('0')
> +			   << buffer->metadata().sequence;
> +			filename.replace(pos, 1, ss.str());
> +		}
> +
> +		qInfo() << "Saving viewfinder to" << filename.c_str();

Use QString instead of std:string, and you can do

		QString filename("%1/picture-%2.jpg");
		filename = filename.arg(defaultPath_)
				   .arg(buffer->metadata().sequence, 6, 10,
				        QLatin1Char('0'));

(and you can drop <sstream>)

> +
> +		QImage image = viewfinder_->getCurrentImage();
> +		QImageWriter writer(QString::fromUtf8(filename.c_str()));
> +		writer.setQuality(95);
> +		writer.write(image);
> +
> +		saveViewfinder_ = false;
> +	}

With this you're adding a delay when taking a snapshot :-S

>  }
>  
>  void MainWindow::queueRequest(FrameBuffer *buffer)
> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
> index 7b8a185511e17a8f..580bcac146fabe07 100644
> --- a/src/qcam/main_window.h
> +++ b/src/qcam/main_window.h
> @@ -54,7 +54,7 @@ private Q_SLOTS:
>  	void switchCamera(int index);
>  	void toggleCapture(bool start);
>  
> -	void saveImageAs();
> +	void saveViewfinder();
>  
>  	void queueRequest(FrameBuffer *buffer);
>  
> @@ -96,6 +96,7 @@ private:
>  
>  	/* Capture state, buffers queue and statistics */
>  	bool isCapturing_;
> +	bool saveViewfinder_;
>  	Stream *vfStream_;
>  	Stream *rawStream_;
>  	std::map<Stream *, QQueue<FrameBuffer *>> freeBuffers_;

Patch

diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 470f78162cabffe5..f57aaf4a27e5f4ca 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -8,6 +8,7 @@ 
 #include "main_window.h"
 
 #include <iomanip>
+#include <sstream>
 #include <string>
 #include <sys/mman.h>
 
@@ -146,8 +147,7 @@  int MainWindow::createToolbars()
 	action = toolbar_->addAction(QIcon::fromTheme("document-save-as",
 						      QIcon(":save.svg")),
 				     "Save As...");
-	action->setShortcut(QKeySequence::SaveAs);
-	connect(action, &QAction::triggered, this, &MainWindow::saveImageAs);
+	connect(action, &QAction::triggered, this, &MainWindow::saveViewfinder);
 
 	return 0;
 }
@@ -509,18 +509,9 @@  void MainWindow::stopCapture()
  * Image Save
  */
 
-void MainWindow::saveImageAs()
+void MainWindow::saveViewfinder()
 {
-	QImage image = viewfinder_->getCurrentImage();
-
-	QString filename = QFileDialog::getSaveFileName(this, "Save Image", defaultPath_,
-							"Image Files (*.png *.jpg *.jpeg)");
-	if (filename.isEmpty())
-		return;
-
-	QImageWriter writer(filename);
-	writer.setQuality(95);
-	writer.write(image);
+	saveViewfinder_ = true;
 }
 
 /* -----------------------------------------------------------------------------
@@ -602,6 +593,29 @@  void MainWindow::processViewfinder(FrameBuffer *buffer)
 
 	/* Render the frame on the viewfinder. */
 	viewfinder_->render(buffer, &mappedBuffers_[buffer]);
+
+	/* Save viewfinder to file if requested. */
+	if (saveViewfinder_) {
+		std::string filename = defaultPath_.toStdString() + "/picture-#.jpeg";
+		size_t pos;
+
+		pos = filename.find_first_of('#');
+		if (pos != std::string::npos) {
+			std::stringstream ss;
+			ss << std::setw(6) << std::setfill('0')
+			   << buffer->metadata().sequence;
+			filename.replace(pos, 1, ss.str());
+		}
+
+		qInfo() << "Saving viewfinder to" << filename.c_str();
+
+		QImage image = viewfinder_->getCurrentImage();
+		QImageWriter writer(QString::fromUtf8(filename.c_str()));
+		writer.setQuality(95);
+		writer.write(image);
+
+		saveViewfinder_ = false;
+	}
 }
 
 void MainWindow::queueRequest(FrameBuffer *buffer)
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index 7b8a185511e17a8f..580bcac146fabe07 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -54,7 +54,7 @@  private Q_SLOTS:
 	void switchCamera(int index);
 	void toggleCapture(bool start);
 
-	void saveImageAs();
+	void saveViewfinder();
 
 	void queueRequest(FrameBuffer *buffer);
 
@@ -96,6 +96,7 @@  private:
 
 	/* Capture state, buffers queue and statistics */
 	bool isCapturing_;
+	bool saveViewfinder_;
 	Stream *vfStream_;
 	Stream *rawStream_;
 	std::map<Stream *, QQueue<FrameBuffer *>> freeBuffers_;