From a0089db75bc9a7056349c25d7c5777fd5db76057 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Thu, 29 Jul 2021 13:13:38 +1200 Subject: [PATCH] - Add a verbose flag and put debugging output being it ("-v" || " --verbose") - In verbose mode draw a thumbnail of the source image in the bottom left of the window - Add support for long options in the command line parsing - Add a "stretch" argument that will stretch the aspect axis to fit the window when set. For example, in landscape mode the drawn picture will be as wide as the window, cropping the top and bottom --- src/imageselector.cpp | 5 +++- src/imageselector.h | 2 ++ src/main.cpp | 45 ++++++++++++++++++++++++++++++++---- src/mainwindow.cpp | 53 +++++++++++++++++++++++++++++++++++++++---- src/mainwindow.h | 7 +++++- src/overlay.cpp | 15 +++++++++--- src/overlay.h | 2 ++ 7 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/imageselector.cpp b/src/imageselector.cpp index 3eb3b7d..e84b9a5 100644 --- a/src/imageselector.cpp +++ b/src/imageselector.cpp @@ -118,7 +118,10 @@ std::string RandomImageSelector::getNextImage() unsigned int RandomImageSelector::selectRandom(const QStringList& images) const { - std::cout << "images: " << images.size() << std::endl; + if(_debugMode) + { + std::cout << "images: " << images.size() << std::endl; + } if (images.size() == 0) { throw std::string("No jpg images found in given folder"); diff --git a/src/imageselector.h b/src/imageselector.h index 8f58089..a11c8c9 100644 --- a/src/imageselector.h +++ b/src/imageselector.h @@ -14,12 +14,14 @@ public: ImageSelector(std::unique_ptr& pathTraverser, char aspect); virtual ~ImageSelector(); virtual std::string getNextImage() = 0; + void setDebugMode(bool debugMode) { _debugMode = debugMode;} protected: int getImageRotation(const std::string &fileName); bool imageValidForAspect(const std::string &fileName); std::unique_ptr& pathTraverser; char _aspect; + bool _debugMode = false; }; class RandomImageSelector : public ImageSelector diff --git a/src/main.cpp b/src/main.cpp index e274d30..accc571 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,13 +8,14 @@ #include #include +#include #include #include #include #include void usage(std::string programName) { - std::cerr << "Usage: " << programName << " [-t rotation_seconds] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-s]" << std::endl; + std::cerr << "Usage: " << programName << " [-t rotation_seconds] [-a aspect('l','p','a')] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-s] [-v] [--verbose] [--stretch]" << std::endl; } int main(int argc, char *argv[]) @@ -29,11 +30,28 @@ int main(int argc, char *argv[]) bool recursive = false; bool shuffle = false; bool sorted = false; + bool debugMode = false; char aspect = 'a'; + bool fitAspectAxisToWindow = false; std::string valid_aspects = "alp"; // all, landscape, portait std::string overlay = ""; - while ((opt = getopt(argc, argv, "b:p:t:o:O:a:rsS")) != -1) { + int debugInt = 0; + int stretchInt = 0; + static struct option long_options[] = + { + {"verbose", no_argument, &debugInt, 1}, + {"stretch", no_argument, &stretchInt, 1}, + }; + int option_index = 0; + while ((opt = getopt_long(argc, argv, "b:p:t:o:O:a:rsSv", long_options, &option_index)) != -1) { switch (opt) { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) + break; + usage(argv[0]); + return 1; + break; case 'p': path = optarg; break; @@ -67,11 +85,22 @@ int main(int argc, char *argv[]) case 'O': overlay = optarg; break; + case 'v': + debugMode = true; + break; default: /* '?' */ usage(argv[0]); return 1; } } + if(debugInt==1) + { + debugMode = true; + } + if(stretchInt==1) + { + fitAspectAxisToWindow = true; + } if (path.empty()) { @@ -103,10 +132,18 @@ int main(int argc, char *argv[]) { selector = std::unique_ptr(new RandomImageSelector(pathTraverser, aspect)); } - std::cout << "Rotation Time: " << rotationSeconds << std::endl; - std::cout << "Overlay input: " << overlay << std::endl; + selector->setDebugMode(debugMode); + if(debugMode) + { + std::cout << "Rotation Time: " << rotationSeconds << std::endl; + std::cout << "Overlay input: " << overlay << std::endl; + } Overlay o(overlay); + o.setDebugMode(debugMode); w.setOverlay(&o); + w.setAspect(aspect); + w.setDebugMode(debugMode); + w.setFitAspectAxisToWindow(fitAspectAxisToWindow); w.show(); ImageSwitcher switcher(w, rotationSeconds * 1000, selector); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9576a80..f283ffb 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -109,6 +109,11 @@ void MainWindow::updateImage(bool immediately) } QPixmap p( currentImage.c_str() ); + if(_debugMode) + { + std::cout << "size:" << p.width() << "x" << p.height() << std::endl; + } + QPixmap rotated = getRotatedPixmap(p); QPixmap scaled = getScaledPixmap(rotated); QPixmap background = getBlurredBackground(rotated, scaled); @@ -120,6 +125,21 @@ void MainWindow::updateImage(bool immediately) drawText(background, overlay->getMarginTopRight(), overlay->getFontsizeTopRight(), overlay->getRenderedTopRight(currentImage).c_str(), Qt::AlignTop|Qt::AlignRight); drawText(background, overlay->getMarginBottomLeft(), overlay->getFontsizeBottomLeft(), overlay->getRenderedBottomLeft(currentImage).c_str(), Qt::AlignBottom|Qt::AlignLeft); drawText(background, overlay->getMarginBottomRight(), overlay->getFontsizeBottomRight(), overlay->getRenderedBottomRight(currentImage).c_str(), Qt::AlignBottom|Qt::AlignRight); + if (_debugMode) + { + // draw a thumbnail version of the source image in the bottom left, to check for cropping issues + QPainter pt(&background); + QBrush brush(QColor(255, 255, 255, 255)); + int margin = 10; + QPixmap thumbNail = p.scaledToWidth(200, Qt::SmoothTransformation); + pt.fillRect(background.width() - thumbNail.width() - 2*margin, + background.height()-thumbNail.height() - 2*margin, + thumbNail.width() +2*margin, thumbNail.height()+2*margin, brush); + + pt.drawPixmap( background.width() - thumbNail.width() - margin, + background.height()-thumbNail.height() - margin, + thumbNail); + } } label->setPixmap(background); @@ -164,13 +184,19 @@ void MainWindow::setOverlay(Overlay* o) overlay = o; } +void MainWindow::setAspect(char aspect) +{ + _aspect = aspect; +} + QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled) { - if (scaled.width() < width()) { + if (scaled.width() < width() || _aspect == 'l') { QPixmap background = blur(originalSize.scaledToWidth(width(), Qt::SmoothTransformation)); QRect rect(0, (background.height() - height())/2, width(), height()); return background.copy(rect); } else { + // aspect 'p' or the image is not as wide as the screen QPixmap background = blur(originalSize.scaledToHeight(height(), Qt::SmoothTransformation)); QRect rect((background.width() - width())/2, 0, width(), height()); return background.copy(rect); @@ -186,9 +212,28 @@ QPixmap MainWindow::getRotatedPixmap(const QPixmap& p) QPixmap MainWindow::getScaledPixmap(const QPixmap& p) { - int w = width(); - int h = height(); - return p.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation); + if (_fitAspectAxisToWindow) + { + if ( _aspect == 'p') + { + // potrait mode, make height of image fit screen and crop top/bottom + QPixmap pTemp = p.scaledToHeight(height(), Qt::SmoothTransformation); + return pTemp.copy(0,0,width(),height()); + } + else if ( _aspect == 'l') + { + // landscape mode, make width of image fit screen and crop top/bottom + QPixmap pTemp = p.scaledToWidth(width(), Qt::SmoothTransformation); + //int imageTempWidth = pTemp.width(); + //int imageTempHeight = pTemp.height(); + return pTemp.copy(0,0,width(),height()); + } + } + + // just scale the best we can for the given photo + int w = width(); + int h = height(); + return p.scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation); } void MainWindow::drawBackground(const QPixmap& originalSize, const QPixmap& scaled) diff --git a/src/mainwindow.h b/src/mainwindow.h index 362a0cc..9de5e9c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -25,13 +25,18 @@ public: void setBackgroundOpacity(unsigned int opacity); void warn(std::string text); void setOverlay(Overlay* overlay); - + void setAspect(char aspect); + void setDebugMode(bool debugMode) {_debugMode = debugMode;} + void setFitAspectAxisToWindow(bool fitAspectAxisToWindow) { _fitAspectAxisToWindow = fitAspectAxisToWindow; } private: Ui::MainWindow *ui; std::string currentImage; unsigned int blurRadius = 20; unsigned int backgroundOpacity = 150; + char _aspect = 'a'; + bool _debugMode = false; + bool _fitAspectAxisToWindow = false; Overlay* overlay; diff --git a/src/overlay.cpp b/src/overlay.cpp index 9bd9aae..94a2a68 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -50,7 +50,10 @@ void Overlay::parseInput() { QString Overlay::getTemplate(QStringList components){ if (components.size()>3) { - std::cout << "template: " << components[3].toStdString() << std::endl; + if(_debugMode) + { + std::cout << "template: " << components[3].toStdString() << std::endl; + } return components[3]; } return ""; @@ -58,7 +61,10 @@ QString Overlay::getTemplate(QStringList components){ int Overlay::getMargin(QStringList components){ if (components.size()>1) { - std::cout << "margin: " << components[1].toStdString() << std::endl; + if(_debugMode) + { + std::cout << "margin: " << components[1].toStdString() << std::endl; + } int num = components[1].toInt(); if (num > 0) { return num; @@ -70,7 +76,10 @@ int Overlay::getMargin(QStringList components){ int Overlay::getFontsize(QStringList components){ if (components.size()>2) { - std::cout << "fontsize: " << components[2].toStdString() << std::endl; + if(_debugMode) + { + std::cout << "fontsize: " << components[2].toStdString() << std::endl; + } int num = components[2].toInt(); if (num > 0) { return num; diff --git a/src/overlay.h b/src/overlay.h index 3707c47..90800f2 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -27,11 +27,13 @@ class Overlay int getMarginBottomRight(); int getFontsizeBottomRight(); + void setDebugMode(const bool debugMode) { _debugMode = debugMode; } private: const std::string overlayInput; int margin; int fontsize; + bool _debugMode = false; QString topLeftTemplate; QString topRightTemplate;