- Add "-a" argument to filter show pictures by aspect ratio (potrait, landscape or all)
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
@@ -31,9 +96,17 @@ std::string RandomImageSelector::getNextImage()
|
|||||||
std:: string filename;
|
std:: string filename;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QStringList images = pathTraverser->getImages();
|
while (filename.empty())
|
||||||
unsigned int selectedImage = selectRandom(images);
|
{
|
||||||
filename = pathTraverser->getImagePath(images.at(selectedImage).toStdString());
|
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)
|
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));
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
19
src/main.cpp
19
src/main.cpp
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user