[{"id":3616,"web_url":"https://patchwork.libcamera.org/comment/3616/","msgid":"<005bf81a-604c-fa48-8b4a-1a5a5e84bab8@ideasonboard.com>","date":"2020-02-06T15:12:02","subject":"Re: [libcamera-devel] [PATCH 6/6] qcam: Provide save image\n\tfunctionality","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi All,\n\nThis one is a bit of an RFC due to comments in the patch:\n\nOn 06/02/2020 15:05, Kieran Bingham wrote:\n> Implement a save image button on the toolbar which will take a current\n> viewfinder image and present the user with a QFileDialog to allow them\n> to choose where to save the image.\n> \n> Utilise the QImageWriter to perform the output task.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  src/qcam/main_window.cpp | 22 ++++++++++++++++++++++\n>  src/qcam/main_window.h   |  1 +\n>  src/qcam/viewfinder.cpp  |  7 +++++++\n>  src/qcam/viewfinder.h    |  2 ++\n>  4 files changed, 32 insertions(+)\n> \n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 0ae4c60b8699..0e994b1e9197 100644\n> --- a/src/qcam/main_window.cpp\n> +++ b/src/qcam/main_window.cpp\n> @@ -11,7 +11,10 @@\n>  #include <sys/mman.h>\n>  \n>  #include <QCoreApplication>\n> +#include <QFileDialog>\n>  #include <QIcon>\n> +#include <QImage>\n> +#include <QImageWriter>\n>  #include <QInputDialog>\n>  #include <QTimer>\n>  #include <QToolBar>\n> @@ -89,6 +92,9 @@ int MainWindow::createToolbars(CameraManager *cm)\n>  \taction = toolbar_->addAction(QIcon(\":stop-circle.svg\"), \"stop\");\n>  \tconnect(action, &QAction::triggered, this, &MainWindow::stopCapture);\n>  \n> +\taction = toolbar_->addAction(QIcon(\":save.svg\"), \"save\");\n> +\tconnect(action, &QAction::triggered, this, &MainWindow::saveImage);\n> +\n>  \treturn 0;\n>  }\n>  \n> @@ -339,6 +345,22 @@ void MainWindow::stopCapture()\n>  \tsetWindowTitle(title_);\n>  }\n>  \n> +void MainWindow::saveImage()\n> +{\n> +\t/* Take a lock to prevent updating the backed image, copy,\n> +\t * then ask where to save with lock released */\n> +\n> +\tQImage image = viewfinder_->getCurrentImage();\n> +\n> +\tQString filename = QFileDialog::getSaveFileName(this, \"Save Image\", \"\",\n> +\t\t\t\t\t\t\t\"Image Files (*.png *.jpg *.jpeg)\");\n> +\n> +\tstd::cerr << \"Save jpeg to \" << filename.toStdString() << std::endl;\n\nI think that can be removed now :-)\n\n> +\n> +\tQImageWriter writer(filename);\n> +\twriter.write(image);\n> +}\n> +\n>  void MainWindow::requestComplete(Request *request)\n>  {\n>  \tif (request->status() == Request::RequestCancelled)\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index b0bf16dd2a09..fc85b6a46491 100644\n> --- a/src/qcam/main_window.h\n> +++ b/src/qcam/main_window.h\n> @@ -48,6 +48,7 @@ private Q_SLOTS:\n>  \n>  \tint startCapture();\n>  \tvoid stopCapture();\n> +\tvoid saveImage();\n>  \n>  private:\n>  \tint createToolbars(CameraManager *cm);\n> diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp\n> index 6de284d1b782..3fa4a326c342 100644\n> --- a/src/qcam/viewfinder.cpp\n> +++ b/src/qcam/viewfinder.cpp\n> @@ -6,6 +6,7 @@\n>   */\n>  \n>  #include <QImage>\n> +#include <QImageWriter>\n>  #include <QPainter>\n>  \n>  #include \"format_converter.h\"\n> @@ -27,6 +28,12 @@ void ViewFinder::display(const unsigned char *raw, size_t size)\n>  \tupdate();\n>  }\n>  \n> +QImage ViewFinder::getCurrentImage()\n> +{\n> +\t/* Ideally need to lock, return/copy, then unlock... Can a scoped lock work? */\n\nSo I 'think' that this might actually be saved from races by the QT\nthreading. But I'm not entirely sure...\n\nThoughts anyone?\n\n> +\treturn *image_;\n\nAnd of course a \"memcpy\" here isn't ideal either - but I anticipate this\ncould all get changed to create a new stream to perform a\nStreamRole::StillCapture type capture ...\n\n\n> +}\n> +\n>  int ViewFinder::setFormat(unsigned int format, unsigned int width,\n>  \t\t\t  unsigned int height)\n>  {\n> diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h\n> index ef5fd45b264a..1da79d3e67aa 100644\n> --- a/src/qcam/viewfinder.h\n> +++ b/src/qcam/viewfinder.h\n> @@ -23,6 +23,8 @@ public:\n>  \t\t      unsigned int height);\n>  \tvoid display(const unsigned char *rgb, size_t size);\n>  \n> +\tQImage getCurrentImage();\n> +\n>  protected:\n>  \tvoid paintEvent(QPaintEvent *) override;\n>  \tQSize sizeHint() const override;\n>","headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B4CFD60874\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  6 Feb 2020 16:12:05 +0100 (CET)","from [192.168.0.20]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3A61B9F0;\n\tThu,  6 Feb 2020 16:12:05 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1581001925;\n\tbh=VQqsKDzk8+7zhm4pl9RWEffabiCJVrL+dySDBH8nZY0=;\n\th=Reply-To:Subject:To:References:From:Date:In-Reply-To:From;\n\tb=QkL/ob7t2qWGIACVpFYReWJwhzCXX83OFDVFC7tzF8Rm5iFhsR2H8QD7vtmCywnAK\n\tUKGWGREjOyNZi0bq37U/Xxu5Z5LoHa86eorZJvCDzya7GIQq0PZQ9LXent8okKtJU8\n\tuOB7HxpUdTUSFNFRCBxMI4UwBTxL7cowKjAUL7DE=","Reply-To":"kieran.bingham@ideasonboard.com","To":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","References":"<20200206150504.24204-1-kieran.bingham@ideasonboard.com>\n\t<20200206150504.24204-7-kieran.bingham@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Openpgp":"preference=signencrypt","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tWZw01QYHU/GUV/zHJSFk","Organization":"Ideas on Board","Message-ID":"<005bf81a-604c-fa48-8b4a-1a5a5e84bab8@ideasonboard.com>","Date":"Thu, 6 Feb 2020 15:12:02 +0000","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101\n\tThunderbird/60.9.1","MIME-Version":"1.0","In-Reply-To":"<20200206150504.24204-7-kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH 6/6] qcam: Provide save image\n\tfunctionality","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Thu, 06 Feb 2020 15:12:05 -0000"}},{"id":3631,"web_url":"https://patchwork.libcamera.org/comment/3631/","msgid":"<20200207001542.GL7611@pendragon.ideasonboard.com>","date":"2020-02-07T00:15:42","subject":"Re: [libcamera-devel] [PATCH 6/6] qcam: Provide save image\n\tfunctionality","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the patch.\n\nOn Thu, Feb 06, 2020 at 03:12:02PM +0000, Kieran Bingham wrote:\n> Hi All,\n> \n> This one is a bit of an RFC due to comments in the patch:\n> \n> On 06/02/2020 15:05, Kieran Bingham wrote:\n> > Implement a save image button on the toolbar which will take a current\n> > viewfinder image and present the user with a QFileDialog to allow them\n> > to choose where to save the image.\n> > \n> > Utilise the QImageWriter to perform the output task.\n> > \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  src/qcam/main_window.cpp | 22 ++++++++++++++++++++++\n> >  src/qcam/main_window.h   |  1 +\n> >  src/qcam/viewfinder.cpp  |  7 +++++++\n> >  src/qcam/viewfinder.h    |  2 ++\n> >  4 files changed, 32 insertions(+)\n> > \n> > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > index 0ae4c60b8699..0e994b1e9197 100644\n> > --- a/src/qcam/main_window.cpp\n> > +++ b/src/qcam/main_window.cpp\n> > @@ -11,7 +11,10 @@\n> >  #include <sys/mman.h>\n> >  \n> >  #include <QCoreApplication>\n> > +#include <QFileDialog>\n> >  #include <QIcon>\n> > +#include <QImage>\n> > +#include <QImageWriter>\n> >  #include <QInputDialog>\n> >  #include <QTimer>\n> >  #include <QToolBar>\n> > @@ -89,6 +92,9 @@ int MainWindow::createToolbars(CameraManager *cm)\n> >  \taction = toolbar_->addAction(QIcon(\":stop-circle.svg\"), \"stop\");\n> >  \tconnect(action, &QAction::triggered, this, &MainWindow::stopCapture);\n> >  \n> > +\taction = toolbar_->addAction(QIcon(\":save.svg\"), \"save\");\n> > +\tconnect(action, &QAction::triggered, this, &MainWindow::saveImage);\n> > +\n> >  \treturn 0;\n> >  }\n> >  \n> > @@ -339,6 +345,22 @@ void MainWindow::stopCapture()\n> >  \tsetWindowTitle(title_);\n> >  }\n> >  \n> > +void MainWindow::saveImage()\n> > +{\n> > +\t/* Take a lock to prevent updating the backed image, copy,\n> > +\t * then ask where to save with lock released */\n\n\t/*\n\t * Take a lock to prevent updating the backed image, copy,\n\t * then ask where to save with lock released.\n\t */\n\n> > +\n> > +\tQImage image = viewfinder_->getCurrentImage();\n> > +\n> > +\tQString filename = QFileDialog::getSaveFileName(this, \"Save Image\", \"\",\n> > +\t\t\t\t\t\t\t\"Image Files (*.png *.jpg *.jpeg)\");\n\nThis is probably OK to start with, but I wonder if we don't also (or\ninstead) need a quicker way to save images, skipping the dialog box. The\nfile name could be computed automatically based on a pattern.\n\n> > +\tstd::cerr << \"Save jpeg to \" << filename.toStdString() << std::endl;\n> \n> I think that can be removed now :-)\n> \n> > +\n> > +\tQImageWriter writer(filename);\n> > +\twriter.write(image);\n> > +}\n> > +\n> >  void MainWindow::requestComplete(Request *request)\n> >  {\n> >  \tif (request->status() == Request::RequestCancelled)\n> > diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> > index b0bf16dd2a09..fc85b6a46491 100644\n> > --- a/src/qcam/main_window.h\n> > +++ b/src/qcam/main_window.h\n> > @@ -48,6 +48,7 @@ private Q_SLOTS:\n> >  \n> >  \tint startCapture();\n> >  \tvoid stopCapture();\n> > +\tvoid saveImage();\n> >  \n> >  private:\n> >  \tint createToolbars(CameraManager *cm);\n> > diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp\n> > index 6de284d1b782..3fa4a326c342 100644\n> > --- a/src/qcam/viewfinder.cpp\n> > +++ b/src/qcam/viewfinder.cpp\n> > @@ -6,6 +6,7 @@\n> >   */\n> >  \n> >  #include <QImage>\n> > +#include <QImageWriter>\n> >  #include <QPainter>\n> >  \n> >  #include \"format_converter.h\"\n> > @@ -27,6 +28,12 @@ void ViewFinder::display(const unsigned char *raw, size_t size)\n> >  \tupdate();\n> >  }\n> >  \n> > +QImage ViewFinder::getCurrentImage()\n> > +{\n> > +\t/* Ideally need to lock, return/copy, then unlock... Can a scoped lock work? */\n> \n> So I 'think' that this might actually be saved from races by the QT\n> threading. But I'm not entirely sure...\n> \n> Thoughts anyone?\n\nMainWindow::requestComplete() is called from the CameraManager thread\n(once the threading patches will be merged, hopefully tomorrow), and\ncalls ViewFinder::display() which updates the contents of the QImage.\nViewFinder::getCurrentImage() is called from the Qt GUI thread, running\nthe main application loop. There's thus a race.\n\n> > +\treturn *image_;\n> \n> And of course a \"memcpy\" here isn't ideal either - but I anticipate this\n> could all get changed to create a new stream to perform a\n> StreamRole::StillCapture type capture ...\n\nThat's true, but we will also need to support cameras that can only\nprovide a single stream.\n\nI think we can implement a more efficient method, at the cost of more\ncomplex code. One option would be to just set a flag in the saveImage()\nfunction, and handling it in requestComplete(). If the flag is set, the\nimage will be saved before requeuing the buffer. We would need to\ndispatch the save action to a separate thread to avoid blocking the\nCameraManager thread.\n\nSaving the last image instead of the next one is also possible, but\nyou'll likely have to allocate two QImage in ViewFinder, switching to\nthe other QImage when save is in progress. It could be a bit messy as\nthe viewfinder would get heavily involved in image capture, which may\nnot be the best design.\n\n> > +}\n> > +\n> >  int ViewFinder::setFormat(unsigned int format, unsigned int width,\n> >  \t\t\t  unsigned int height)\n> >  {\n> > diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h\n> > index ef5fd45b264a..1da79d3e67aa 100644\n> > --- a/src/qcam/viewfinder.h\n> > +++ b/src/qcam/viewfinder.h\n> > @@ -23,6 +23,8 @@ public:\n> >  \t\t      unsigned int height);\n> >  \tvoid display(const unsigned char *rgb, size_t size);\n> >  \n> > +\tQImage getCurrentImage();\n> > +\n> >  protected:\n> >  \tvoid paintEvent(QPaintEvent *) override;\n> >  \tQSize sizeHint() const override;","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B15760864\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  7 Feb 2020 01:15:58 +0100 (CET)","from pendragon.ideasonboard.com\n\t(117.145-247-81.adsl-dyn.isp.belgacom.be [81.247.145.117])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8EA1F9CE;\n\tFri,  7 Feb 2020 01:15:57 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1581034557;\n\tbh=EDAHE9+vAS+0YiRkKCAFuYJdzXDjb4yv5wtxuHBGbuY=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=dlKSCzzMCjY2iFx5R0c8753klyUKNR5AA1q4MP4+M64SQh2TRmjc9piWyZ4gONtRQ\n\tlIqG32vms2XM7c7XLI+Fthkga0Eo5wcTIFVjwg2vb6VxdwWF07riU1fq6PNH05B4Ew\n\tS9ZTOCUfQdzTQ1+wKhyj7kb04J8bAkkoeMP042zg=","Date":"Fri, 7 Feb 2020 02:15:42 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"LibCamera Devel <libcamera-devel@lists.libcamera.org>","Message-ID":"<20200207001542.GL7611@pendragon.ideasonboard.com>","References":"<20200206150504.24204-1-kieran.bingham@ideasonboard.com>\n\t<20200206150504.24204-7-kieran.bingham@ideasonboard.com>\n\t<005bf81a-604c-fa48-8b4a-1a5a5e84bab8@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<005bf81a-604c-fa48-8b4a-1a5a5e84bab8@ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH 6/6] qcam: Provide save image\n\tfunctionality","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Fri, 07 Feb 2020 00:15:58 -0000"}}]