- 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

@@ -5,21 +5,86 @@
#include <QTimer>
#include <QApplication>
#include <QDir>
#include <libexif/exif-data.h>
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <algorithm> // std::shuffle
#include <random> // std::default_random_engine
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser):
pathTraverser(pathTraverser)
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
pathTraverser(pathTraverser), _aspect(aspect)
{
}
ImageSelector::~ImageSelector(){}
RandomImageSelector::RandomImageSelector(std::unique_ptr<PathTraverser>& 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>& 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>& pathTraverser):
ImageSelector(pathTraverser),
ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& 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>& pathTraverser):
ImageSelector(pathTraverser),
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
ImageSelector(pathTraverser, aspect),
images()
{
srand (time(NULL));

View File

@@ -11,18 +11,21 @@ class PathTraverser;
class ImageSelector
{
public:
ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
ImageSelector(std::unique_ptr<PathTraverser>& 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>& pathTraverser;
char _aspect;
};
class RandomImageSelector : public ImageSelector
{
public:
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~RandomImageSelector();
virtual std::string getNextImage();
@@ -33,7 +36,7 @@ private:
class ShuffleImageSelector : public ImageSelector
{
public:
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~ShuffleImageSelector();
virtual std::string getNextImage();
@@ -45,7 +48,7 @@ private:
class SortedImageSelector : public ImageSelector
{
public:
SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser);
SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
virtual ~SortedImageSelector();
virtual std::string getNextImage();

View File

@@ -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<ImageSelector> selector;
if (sorted)
{
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser));
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser, aspect));
}
else if (shuffle)
{
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser));
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser, aspect));
}
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;
Overlay o(overlay);
w.setOverlay(&o);