From 23a0e208bf149b455ed39a2521e6848df4e0e750 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Thu, 29 Jul 2021 11:52:32 +1200 Subject: [PATCH 1/9] - Add "-a" argument to filter show pictures by aspect ratio (potrait, landscape or all) --- README.md | 3 +- src/imageselector.cpp | 95 ++++++++++++++++++++++++++++++++++++++----- src/imageselector.h | 11 +++-- src/main.cpp | 19 +++++++-- 4 files changed, 108 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index f2880ea..0476258 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This project is maintained by myself during my spare time. If you like and use i ## Usage ``` -slide [-t rotation_seconds] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-O overlay_string] +slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-O overlay_string] ``` * `image_folder`: where to search for images (.jpg files) @@ -25,6 +25,7 @@ slide [-t rotation_seconds] [-o background_opacity(0..255)] [-b blur_radius] -p * `-s` for shuffle instead of random image rotation * `-S` for sorted rotation (files ordered by name, first images then subfolders) * `rotation_seconds(default=30)`: time until next random image is chosen from the given folder +* `aspect(default=a)`: the required aspect ratio of the picture to display. Valid values are 'a' (all), 'l' (landscape) and 'p' (portrait) * `background_opacity(default=150)`: opacity of the background filling image between 0 (black background) and 255 * `blur_radius(default=20)`: blur radius of the background filling image * `-O` is used to create a overlay string. diff --git a/src/imageselector.cpp b/src/imageselector.cpp index 3d082d6..3eb3b7d 100644 --- a/src/imageselector.cpp +++ b/src/imageselector.cpp @@ -5,21 +5,86 @@ #include #include #include +#include #include #include /* srand, rand */ #include /* time */ #include // std::shuffle #include // std::default_random_engine -ImageSelector::ImageSelector(std::unique_ptr& pathTraverser): - pathTraverser(pathTraverser) +ImageSelector::ImageSelector(std::unique_ptr& pathTraverser, char aspect): + pathTraverser(pathTraverser), _aspect(aspect) { } ImageSelector::~ImageSelector(){} -RandomImageSelector::RandomImageSelector(std::unique_ptr& pathTraverser): - ImageSelector(pathTraverser) +int ImageSelector::getImageRotation(const std::string &fileName) +{ + int orientation = 0; + ExifData *exifData = exif_data_new_from_file(fileName.c_str()); + if (exifData) + { + ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); + ExifEntry *exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION); + + if (exifEntry) + { + orientation = exif_get_short(exifEntry->data, byteOrder); + } + exif_data_free(exifData); + } + + int degrees = 0; + switch(orientation) { + case 8: + degrees = 270; + break; + case 3: + degrees = 180; + break; + case 6: + degrees = 90; + break; + } + return degrees; +} + +bool ImageSelector::imageValidForAspect(const std::string &fileName) +{ + QPixmap p( fileName.c_str() ); + int imageWidth = p.width(); + int imageHeight = p.height(); + int rotation = getImageRotation(fileName); + if ( rotation == 90 || rotation == 270 ) + { + std::swap(imageWidth,imageHeight); + } + + switch(_aspect) + { + case 'a': + // allow all + break; + case 'l': + if ( imageWidth < imageHeight ) + { + return false; + } + break; + case 'p': + if ( imageHeight < imageWidth ) + { + return false; + } + break; + } + return true; +} + + +RandomImageSelector::RandomImageSelector(std::unique_ptr& pathTraverser, char aspect): + ImageSelector(pathTraverser, aspect) { srand (time(NULL)); } @@ -31,9 +96,17 @@ std::string RandomImageSelector::getNextImage() std:: string filename; try { - QStringList images = pathTraverser->getImages(); - unsigned int selectedImage = selectRandom(images); - filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString()); + while (filename.empty()) + { + QStringList images = pathTraverser->getImages(); + unsigned int selectedImage = selectRandom(images); + filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString()); + if (!imageValidForAspect(filename)) + { + filename.clear(); + } + } + } catch(const std::string& err) { @@ -53,8 +126,8 @@ unsigned int RandomImageSelector::selectRandom(const QStringList& images) const return rand() % images.size(); } -ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr& pathTraverser): - ImageSelector(pathTraverser), +ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr& pathTraverser, char aspect): + ImageSelector(pathTraverser, aspect), current_image_shuffle(-1), images() { @@ -92,8 +165,8 @@ std::string ShuffleImageSelector::getNextImage() return filename; } -SortedImageSelector::SortedImageSelector(std::unique_ptr& pathTraverser): - ImageSelector(pathTraverser), +SortedImageSelector::SortedImageSelector(std::unique_ptr& pathTraverser, char aspect): + ImageSelector(pathTraverser, aspect), images() { srand (time(NULL)); diff --git a/src/imageselector.h b/src/imageselector.h index dc73b83..8f58089 100644 --- a/src/imageselector.h +++ b/src/imageselector.h @@ -11,18 +11,21 @@ class PathTraverser; class ImageSelector { public: - ImageSelector(std::unique_ptr& pathTraverser); + ImageSelector(std::unique_ptr& pathTraverser, char aspect); virtual ~ImageSelector(); virtual std::string getNextImage() = 0; protected: + int getImageRotation(const std::string &fileName); + bool imageValidForAspect(const std::string &fileName); std::unique_ptr& pathTraverser; + char _aspect; }; class RandomImageSelector : public ImageSelector { public: - RandomImageSelector(std::unique_ptr& pathTraverser); + RandomImageSelector(std::unique_ptr& pathTraverser, char aspect); virtual ~RandomImageSelector(); virtual std::string getNextImage(); @@ -33,7 +36,7 @@ private: class ShuffleImageSelector : public ImageSelector { public: - ShuffleImageSelector(std::unique_ptr& pathTraverser); + ShuffleImageSelector(std::unique_ptr& pathTraverser, char aspect); virtual ~ShuffleImageSelector(); virtual std::string getNextImage(); @@ -45,7 +48,7 @@ private: class SortedImageSelector : public ImageSelector { public: - SortedImageSelector(std::unique_ptr& pathTraverser); + SortedImageSelector(std::unique_ptr& pathTraverser, char aspect); virtual ~SortedImageSelector(); virtual std::string getNextImage(); diff --git a/src/main.cpp b/src/main.cpp index 8943b49..e274d30 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,12 +29,22 @@ int main(int argc, char *argv[]) bool recursive = false; bool shuffle = false; bool sorted = false; + char aspect = 'a'; + std::string valid_aspects = "alp"; // all, landscape, portait std::string overlay = ""; - while ((opt = getopt(argc, argv, "b:p:t:o:O:rsS")) != -1) { + while ((opt = getopt(argc, argv, "b:p:t:o:O:a:rsS")) != -1) { switch (opt) { case 'p': path = optarg; break; + case 'a': + aspect = optarg[0]; + if ( valid_aspects.find(aspect) == std::string::npos ) + { + std::cout << "Invalid Aspect option, defaulting to all" << std::endl; + aspect = 'a'; + } + break; case 't': rotationSeconds = atoi(optarg); break; @@ -83,16 +93,17 @@ int main(int argc, char *argv[]) std::unique_ptr selector; if (sorted) { - selector = std::unique_ptr(new SortedImageSelector(pathTraverser)); + selector = std::unique_ptr(new SortedImageSelector(pathTraverser, aspect)); } else if (shuffle) { - selector = std::unique_ptr(new ShuffleImageSelector(pathTraverser)); + selector = std::unique_ptr(new ShuffleImageSelector(pathTraverser, aspect)); } else { - selector = std::unique_ptr(new RandomImageSelector(pathTraverser)); + selector = std::unique_ptr(new RandomImageSelector(pathTraverser, aspect)); } + std::cout << "Rotation Time: " << rotationSeconds << std::endl; std::cout << "Overlay input: " << overlay << std::endl; Overlay o(overlay); w.setOverlay(&o); From bee9a78986d01cf266d504a98643abac7c9f0441 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Thu, 29 Jul 2021 11:53:55 +1200 Subject: [PATCH 2/9] - Add the build and .vscode folders to gitignore - Make the build target dependent on files in the src/ folder --- .gitignore | 2 ++ Makefile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 258bec7..d46ff1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ make .swp .git +build +.vscode diff --git a/Makefile b/Makefile index d7c1d8e..462e726 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ check-deps-deb: clean: rm -rf build -build: +build: $(shell find src -type f) mkdir -p build qmake src/slide.pro -o build/Makefile make -C build From a0089db75bc9a7056349c25d7c5777fd5db76057 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Thu, 29 Jul 2021 13:13:38 +1200 Subject: [PATCH 3/9] - 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; From 5ba3fef3305f51ec7623244d9319bc5c51ec9330 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Thu, 29 Jul 2021 13:17:17 +1200 Subject: [PATCH 4/9] - update docs with new verbose and stretch flags --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0476258..0246fe4 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This project is maintained by myself during my spare time. If you like and use i ## Usage ``` -slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-O overlay_string] +slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur_radius] -p image_folder [-r] [-O overlay_string] [-v] [--verbose] [--stretch] ``` * `image_folder`: where to search for images (.jpg files) @@ -28,6 +28,8 @@ slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur * `aspect(default=a)`: the required aspect ratio of the picture to display. Valid values are 'a' (all), 'l' (landscape) and 'p' (portrait) * `background_opacity(default=150)`: opacity of the background filling image between 0 (black background) and 255 * `blur_radius(default=20)`: blur radius of the background filling image +* `-v` or `--verbose`: Verbose debug output when running, plus a thumbnail of the original image in the bottom left of the screen +* `--stretch`: When in aspect mode 'l' or 'p' crop the image rather than leaving a blurred background. For example, in landscape mode this will make images as wide as the screen and crop the top and bottom to fit. * `-O` is used to create a overlay string. * It defines overlays for all four edges in the order `top-left;top-right;bottom-left;bottom-right` * All edges overlays are separated by `;` From 019b9406bcbda5c0d59aa8ca9eeb2e650c05e0da Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Fri, 30 Jul 2021 17:57:01 +1200 Subject: [PATCH 5/9] - If you fail to load content try on a different timer (every 5 seconds by default). This fixes slow image loading at startup if you have a long timeout between pictures. --- src/imageswitcher.cpp | 6 +++++- src/imageswitcher.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/imageswitcher.cpp b/src/imageswitcher.cpp index e64979d..5e57331 100644 --- a/src/imageswitcher.cpp +++ b/src/imageswitcher.cpp @@ -14,7 +14,8 @@ ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeout, std::unique_pt window(w), timeout(timeout), selector(selector), - timer(this) + timer(this), + timerNoContent(this) { } @@ -24,10 +25,12 @@ void ImageSwitcher::updateImage() if (filename == "") { window.warn("No image found."); + timerNoContent.start(timeoutNoContent); } else { window.setImage(filename); + timerNoContent.stop(); // we have loaded content so stop the fast polling } } @@ -35,5 +38,6 @@ void ImageSwitcher::start() { updateImage(); connect(&timer, SIGNAL(timeout()), this, SLOT(updateImage())); + connect(&timerNoContent, SIGNAL(timeout()), this, SLOT(updateImage())); timer.start(timeout); } diff --git a/src/imageswitcher.h b/src/imageswitcher.h index d49d3ad..fbfbcf6 100644 --- a/src/imageswitcher.h +++ b/src/imageswitcher.h @@ -22,6 +22,8 @@ private: unsigned int timeout; std::unique_ptr& selector; QTimer timer; + const unsigned int timeoutNoContent = 5 * 1000; // 10 sec + QTimer timerNoContent; }; #endif // IMAGESWITCHER_H From 4132f65b2e8f3c8a0942144517b8b43b98a6fbc4 Mon Sep 17 00:00:00 2001 From: alfred-reynolds <31379500+alfred-reynolds@users.noreply.github.com> Date: Sat, 31 Jul 2021 13:59:05 +1200 Subject: [PATCH 6/9] - fix comment Co-authored-by: Manuel Dewald --- src/imageswitcher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imageswitcher.h b/src/imageswitcher.h index fbfbcf6..f0f665c 100644 --- a/src/imageswitcher.h +++ b/src/imageswitcher.h @@ -22,7 +22,7 @@ private: unsigned int timeout; std::unique_ptr& selector; QTimer timer; - const unsigned int timeoutNoContent = 5 * 1000; // 10 sec + const unsigned int timeoutNoContent = 5 * 1000; // 5 sec QTimer timerNoContent; }; From 455a7946695fca2a5c75116b320e4f6c87d8cb40 Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Sat, 31 Jul 2021 14:18:01 +1200 Subject: [PATCH 7/9] - Remove "_" prefix on members - Remove aspect check getBlurredBackground as it is not needed --- src/imageselector.cpp | 8 ++++---- src/imageselector.h | 8 ++++---- src/mainwindow.cpp | 16 ++++++++-------- src/mainwindow.h | 12 ++++++------ src/overlay.cpp | 6 +++--- src/overlay.h | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/imageselector.cpp b/src/imageselector.cpp index e84b9a5..c2f7306 100644 --- a/src/imageselector.cpp +++ b/src/imageselector.cpp @@ -12,8 +12,8 @@ #include // std::shuffle #include // std::default_random_engine -ImageSelector::ImageSelector(std::unique_ptr& pathTraverser, char aspect): - pathTraverser(pathTraverser), _aspect(aspect) +ImageSelector::ImageSelector(std::unique_ptr& pathTraverser, char aspectIn): + pathTraverser(pathTraverser), aspect(aspectIn) { } @@ -61,7 +61,7 @@ bool ImageSelector::imageValidForAspect(const std::string &fileName) std::swap(imageWidth,imageHeight); } - switch(_aspect) + switch(aspect) { case 'a': // allow all @@ -118,7 +118,7 @@ std::string RandomImageSelector::getNextImage() unsigned int RandomImageSelector::selectRandom(const QStringList& images) const { - if(_debugMode) + if(debugMode) { std::cout << "images: " << images.size() << std::endl; } diff --git a/src/imageselector.h b/src/imageselector.h index a11c8c9..645f5af 100644 --- a/src/imageselector.h +++ b/src/imageselector.h @@ -11,17 +11,17 @@ class PathTraverser; class ImageSelector { public: - ImageSelector(std::unique_ptr& pathTraverser, char aspect); + ImageSelector(std::unique_ptr& pathTraverser, char aspectIn); virtual ~ImageSelector(); virtual std::string getNextImage() = 0; - void setDebugMode(bool debugMode) { _debugMode = debugMode;} + void setDebugMode(bool debugModeIn) { debugMode = debugModeIn;} protected: int getImageRotation(const std::string &fileName); bool imageValidForAspect(const std::string &fileName); std::unique_ptr& pathTraverser; - char _aspect; - bool _debugMode = false; + char aspect; + bool debugMode = false; }; class RandomImageSelector : public ImageSelector diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f283ffb..804a212 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -109,7 +109,7 @@ void MainWindow::updateImage(bool immediately) } QPixmap p( currentImage.c_str() ); - if(_debugMode) + if(debugMode) { std::cout << "size:" << p.width() << "x" << p.height() << std::endl; } @@ -125,7 +125,7 @@ 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) + if (debugMode) { // draw a thumbnail version of the source image in the bottom left, to check for cropping issues QPainter pt(&background); @@ -184,14 +184,14 @@ void MainWindow::setOverlay(Overlay* o) overlay = o; } -void MainWindow::setAspect(char aspect) +void MainWindow::setAspect(char aspectIn) { - _aspect = aspect; + aspect = aspectIn; } QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled) { - if (scaled.width() < width() || _aspect == 'l') { + if (scaled.width() < width()) { QPixmap background = blur(originalSize.scaledToWidth(width(), Qt::SmoothTransformation)); QRect rect(0, (background.height() - height())/2, width(), height()); return background.copy(rect); @@ -212,15 +212,15 @@ QPixmap MainWindow::getRotatedPixmap(const QPixmap& p) QPixmap MainWindow::getScaledPixmap(const QPixmap& p) { - if (_fitAspectAxisToWindow) + if (fitAspectAxisToWindow) { - if ( _aspect == 'p') + 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') + else if ( aspect == 'l') { // landscape mode, make width of image fit screen and crop top/bottom QPixmap pTemp = p.scaledToWidth(width(), Qt::SmoothTransformation); diff --git a/src/mainwindow.h b/src/mainwindow.h index 9de5e9c..d83f436 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -25,18 +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; } + void setAspect(char aspectIn); + void setDebugMode(bool debugModeIn) {debugMode = debugModeIn;} + void setFitAspectAxisToWindow(bool fitAspectAxisToWindowIn) { fitAspectAxisToWindow = fitAspectAxisToWindowIn; } private: Ui::MainWindow *ui; std::string currentImage; unsigned int blurRadius = 20; unsigned int backgroundOpacity = 150; - char _aspect = 'a'; - bool _debugMode = false; - bool _fitAspectAxisToWindow = false; + char aspect = 'a'; + bool debugMode = false; + bool fitAspectAxisToWindow = false; Overlay* overlay; diff --git a/src/overlay.cpp b/src/overlay.cpp index 94a2a68..9d43572 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -50,7 +50,7 @@ void Overlay::parseInput() { QString Overlay::getTemplate(QStringList components){ if (components.size()>3) { - if(_debugMode) + if(debugMode) { std::cout << "template: " << components[3].toStdString() << std::endl; } @@ -61,7 +61,7 @@ QString Overlay::getTemplate(QStringList components){ int Overlay::getMargin(QStringList components){ if (components.size()>1) { - if(_debugMode) + if(debugMode) { std::cout << "margin: " << components[1].toStdString() << std::endl; } @@ -76,7 +76,7 @@ int Overlay::getMargin(QStringList components){ int Overlay::getFontsize(QStringList components){ if (components.size()>2) { - if(_debugMode) + if(debugMode) { std::cout << "fontsize: " << components[2].toStdString() << std::endl; } diff --git a/src/overlay.h b/src/overlay.h index 90800f2..b1cef0a 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -27,13 +27,13 @@ class Overlay int getMarginBottomRight(); int getFontsizeBottomRight(); - void setDebugMode(const bool debugMode) { _debugMode = debugMode; } + void setDebugMode(const bool debugModeIn) { debugMode = debugModeIn; } private: const std::string overlayInput; int margin; int fontsize; - bool _debugMode = false; + bool debugMode = false; QString topLeftTemplate; QString topRightTemplate; From 75c50a42096ab865297cdb7d1275867ac5ddfdcf Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Sat, 31 Jul 2021 14:42:13 +1200 Subject: [PATCH 8/9] - Implement aspect ratio checking for the shuffle and sorted image list modes --- src/imageselector.cpp | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/imageselector.cpp b/src/imageselector.cpp index c2f7306..5271291 100644 --- a/src/imageselector.cpp +++ b/src/imageselector.cpp @@ -159,8 +159,20 @@ std::string ShuffleImageSelector::getNextImage() std::string filename = pathTraverser->getImagePath(images.at(current_image_shuffle).toStdString()); if(!QFileInfo::exists(QString(filename.c_str()))) { - std::cout << "file not found: " << filename << std::endl; - current_image_shuffle = images.size(); + if(debugMode) + { + std::cout << "file not found: " << filename << std::endl; + } + current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image + return getNextImage(); + } + if (!imageValidForAspect(filename)) + { + if(debugMode) + { + std::cout << "image has invalid aspect: " << filename << "(images left:" << (images.size()-current_image_shuffle) << ")" << std::endl; + } + current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image return getNextImage(); } std::cout << "updating image: " << filename << std::endl; @@ -197,10 +209,13 @@ std::string SortedImageSelector::getNextImage() { images = pathTraverser->getImages(); std::sort(images.begin(), images.end()); - std::cout << "read " << images.size() << " images." << std::endl; - for (int i = 0;i getImagePath(images.takeFirst().toStdString()); if(!QFileInfo::exists(QString(filename.c_str()))) { - std::cout << "file not found: " << filename << std::endl; + if(debugMode) + { + std::cout << "file not found: " << filename << std::endl; + } return getNextImage(); } + if (!imageValidForAspect(filename)) + { + if(debugMode) + { + std::cout << "image has invalid aspect: " << filename << std::endl; + } + return getNextImage(); + } + std::cout << "updating image: " << filename << std::endl; return filename; } From e238719740a970a41ede83db548a668cfdc947eb Mon Sep 17 00:00:00 2001 From: Alfred Reynolds Date: Sun, 1 Aug 2021 13:46:19 +1200 Subject: [PATCH 9/9] - fix --stretch mode, we need to make sure the background texture matches the screen size, so when we composite the foreground in the drawForeground() we fil the screen --- src/mainwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 804a212..6c0aa85 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -191,7 +191,10 @@ void MainWindow::setAspect(char aspectIn) QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled) { - if (scaled.width() < width()) { + if (fitAspectAxisToWindow) { + // our scaled version will just fill the whole screen, us it directly + return scaled.copy(); + } else if (scaled.width() < width()) { QPixmap background = blur(originalSize.scaledToWidth(width(), Qt::SmoothTransformation)); QRect rect(0, (background.height() - height())/2, width(), height()); return background.copy(rect);