- Add "-a" argument to filter show pictures by aspect ratio (potrait, landscape or all)

This commit is contained in:
Alfred Reynolds
2021-07-29 11:52:32 +12:00
parent 4dddda44e7
commit 23a0e208bf
4 changed files with 108 additions and 20 deletions

View File

@@ -17,7 +17,7 @@ This project is maintained by myself during my spare time. If you like and use i
## Usage ## 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) * `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 shuffle instead of random image rotation
* `-S` for sorted rotation (files ordered by name, first images then subfolders) * `-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 * `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 * `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 * `blur_radius(default=20)`: blur radius of the background filling image
* `-O` is used to create a overlay string. * `-O` is used to create a overlay string.

View File

@@ -5,21 +5,86 @@
#include <QTimer> #include <QTimer>
#include <QApplication> #include <QApplication>
#include <QDir> #include <QDir>
#include <libexif/exif-data.h>
#include <iostream> #include <iostream>
#include <stdlib.h> /* srand, rand */ #include <stdlib.h> /* srand, rand */
#include <time.h> /* time */ #include <time.h> /* time */
#include <algorithm> // std::shuffle #include <algorithm> // std::shuffle
#include <random> // std::default_random_engine #include <random> // std::default_random_engine
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser): ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
pathTraverser(pathTraverser) pathTraverser(pathTraverser), _aspect(aspect)
{ {
} }
ImageSelector::~ImageSelector(){} ImageSelector::~ImageSelector(){}
RandomImageSelector::RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser): int ImageSelector::getImageRotation(const std::string &fileName)
ImageSelector(pathTraverser) {
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>& pathTraverser, char aspect):
ImageSelector(pathTraverser, aspect)
{ {
srand (time(NULL)); srand (time(NULL));
} }
@@ -30,10 +95,18 @@ std::string RandomImageSelector::getNextImage()
{ {
std:: string filename; std:: string filename;
try try
{
while (filename.empty())
{ {
QStringList images = pathTraverser->getImages(); QStringList images = pathTraverser->getImages();
unsigned int selectedImage = selectRandom(images); unsigned int selectedImage = selectRandom(images);
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString()); filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
if (!imageValidForAspect(filename))
{
filename.clear();
}
}
} }
catch(const std::string& err) catch(const std::string& err)
{ {
@@ -53,8 +126,8 @@ unsigned int RandomImageSelector::selectRandom(const QStringList& images) const
return rand() % images.size(); return rand() % images.size();
} }
ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser): ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
ImageSelector(pathTraverser), ImageSelector(pathTraverser, aspect),
current_image_shuffle(-1), current_image_shuffle(-1),
images() images()
{ {
@@ -92,8 +165,8 @@ std::string ShuffleImageSelector::getNextImage()
return filename; return filename;
} }
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser): SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
ImageSelector(pathTraverser), ImageSelector(pathTraverser, aspect),
images() images()
{ {
srand (time(NULL)); srand (time(NULL));

View File

@@ -11,18 +11,21 @@ class PathTraverser;
class ImageSelector class ImageSelector
{ {
public: public:
ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser); ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~ImageSelector(); virtual ~ImageSelector();
virtual std::string getNextImage() = 0; virtual std::string getNextImage() = 0;
protected: protected:
int getImageRotation(const std::string &fileName);
bool imageValidForAspect(const std::string &fileName);
std::unique_ptr<PathTraverser>& pathTraverser; std::unique_ptr<PathTraverser>& pathTraverser;
char _aspect;
}; };
class RandomImageSelector : public ImageSelector class RandomImageSelector : public ImageSelector
{ {
public: public:
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser); RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~RandomImageSelector(); virtual ~RandomImageSelector();
virtual std::string getNextImage(); virtual std::string getNextImage();
@@ -33,7 +36,7 @@ private:
class ShuffleImageSelector : public ImageSelector class ShuffleImageSelector : public ImageSelector
{ {
public: public:
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser); ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~ShuffleImageSelector(); virtual ~ShuffleImageSelector();
virtual std::string getNextImage(); virtual std::string getNextImage();
@@ -45,7 +48,7 @@ private:
class SortedImageSelector : public ImageSelector class SortedImageSelector : public ImageSelector
{ {
public: public:
SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser); SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~SortedImageSelector(); virtual ~SortedImageSelector();
virtual std::string getNextImage(); virtual std::string getNextImage();

View File

@@ -29,12 +29,22 @@ int main(int argc, char *argv[])
bool recursive = false; bool recursive = false;
bool shuffle = false; bool shuffle = false;
bool sorted = false; bool sorted = false;
char aspect = 'a';
std::string valid_aspects = "alp"; // all, landscape, portait
std::string overlay = ""; 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) { switch (opt) {
case 'p': case 'p':
path = optarg; path = optarg;
break; 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': case 't':
rotationSeconds = atoi(optarg); rotationSeconds = atoi(optarg);
break; break;
@@ -83,16 +93,17 @@ int main(int argc, char *argv[])
std::unique_ptr<ImageSelector> selector; std::unique_ptr<ImageSelector> selector;
if (sorted) if (sorted)
{ {
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser)); selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser, aspect));
} }
else if (shuffle) else if (shuffle)
{ {
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser)); selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser, aspect));
} }
else else
{ {
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser)); selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser, aspect));
} }
std::cout << "Rotation Time: " << rotationSeconds << std::endl;
std::cout << "Overlay input: " << overlay << std::endl; std::cout << "Overlay input: " << overlay << std::endl;
Overlay o(overlay); Overlay o(overlay);
w.setOverlay(&o); w.setOverlay(&o);