- Add support for per folder image display options. The file called options.json contains json keys to control image options when displaying files in this folder. Currently a singled option, fitAspectAxisToWindow, is supported
- Remove duplicated image rotation reading code, have the image selector logic just pass this up via the per image options
This commit is contained in:
11
README.md
11
README.md
@@ -46,7 +46,16 @@ slide [-t rotation_seconds] [-a aspect] [-o background_opacity(0..255)] [-b blur
|
|||||||
* `<dir>`directory of the current image
|
* `<dir>`directory of the current image
|
||||||
* `<path>`path to the current image without filename
|
* `<path>`path to the current image without filename
|
||||||
* Example: `slide -p ./images -O "20|60|Time: <time>;;;Picture taken at <exifdatetime>"`
|
* Example: `slide -p ./images -O "20|60|Time: <time>;;;Picture taken at <exifdatetime>"`
|
||||||
|
|
||||||
|
## Folder Options file
|
||||||
|
When using the default or recursive folder mode we support having per folder display options. The options are stored in a file called "options.json" and currently support the following option
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"fitAspectAxisToWindow": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
* `fitAspectAxisToWindow` : apply the --stretch option to files in this folder
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
* qt5-qmake
|
* qt5-qmake
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#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, char aspectIn):
|
ImageSelector::ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspectIn, bool fitAspectAxisToWindowIn):
|
||||||
pathTraverser(pathTraverser), aspect(aspectIn)
|
pathTraverser(pathTraverser), aspect(aspectIn), fitAspectAxisToWindow(fitAspectAxisToWindowIn)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +50,11 @@ int ImageSelector::getImageRotation(const std::string &fileName)
|
|||||||
return degrees;
|
return degrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageSelector::imageValidForAspect(const std::string &fileName)
|
bool ImageSelector::imageValidForAspect(const std::string &fileName, const int rotation)
|
||||||
{
|
{
|
||||||
QPixmap p( fileName.c_str() );
|
QPixmap p( fileName.c_str() );
|
||||||
int imageWidth = p.width();
|
int imageWidth = p.width();
|
||||||
int imageHeight = p.height();
|
int imageHeight = p.height();
|
||||||
int rotation = getImageRotation(fileName);
|
|
||||||
if ( rotation == 90 || rotation == 270 )
|
if ( rotation == 90 || rotation == 270 )
|
||||||
{
|
{
|
||||||
std::swap(imageWidth,imageHeight);
|
std::swap(imageWidth,imageHeight);
|
||||||
@@ -83,15 +82,15 @@ bool ImageSelector::imageValidForAspect(const std::string &fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RandomImageSelector::RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
|
RandomImageSelector::RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow):
|
||||||
ImageSelector(pathTraverser, aspect)
|
ImageSelector(pathTraverser, aspect, fitAspectAxisToWindow)
|
||||||
{
|
{
|
||||||
srand (time(NULL));
|
srand (time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomImageSelector::~RandomImageSelector(){}
|
RandomImageSelector::~RandomImageSelector(){}
|
||||||
|
|
||||||
std::string RandomImageSelector::getNextImage()
|
const std::string RandomImageSelector::getNextImage(ImageOptions_t &options)
|
||||||
{
|
{
|
||||||
std:: string filename;
|
std:: string filename;
|
||||||
try
|
try
|
||||||
@@ -101,7 +100,8 @@ std::string RandomImageSelector::getNextImage()
|
|||||||
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))
|
options.rotation = getImageRotation(filename);
|
||||||
|
if (!imageValidForAspect(filename, options.rotation))
|
||||||
{
|
{
|
||||||
filename.clear();
|
filename.clear();
|
||||||
}
|
}
|
||||||
@@ -113,6 +113,9 @@ std::string RandomImageSelector::getNextImage()
|
|||||||
std::cerr << "Error: " << err << std::endl;
|
std::cerr << "Error: " << err << std::endl;
|
||||||
}
|
}
|
||||||
std::cout << "updating image: " << filename << std::endl;
|
std::cout << "updating image: " << filename << std::endl;
|
||||||
|
options.aspect = aspect;
|
||||||
|
options.fitAspectAxisToWindow = fitAspectAxisToWindow;
|
||||||
|
pathTraverser->UpdateOptionsForImage(filename, options);
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,8 +132,8 @@ unsigned int RandomImageSelector::selectRandom(const QStringList& images) const
|
|||||||
return rand() % images.size();
|
return rand() % images.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
|
ShuffleImageSelector::ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow):
|
||||||
ImageSelector(pathTraverser, aspect),
|
ImageSelector(pathTraverser, aspect, fitAspectAxisToWindow),
|
||||||
current_image_shuffle(-1),
|
current_image_shuffle(-1),
|
||||||
images()
|
images()
|
||||||
{
|
{
|
||||||
@@ -141,7 +144,7 @@ ShuffleImageSelector::~ShuffleImageSelector()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ShuffleImageSelector::getNextImage()
|
const std::string ShuffleImageSelector::getNextImage(ImageOptions_t &options)
|
||||||
{
|
{
|
||||||
if (images.size() == 0 || current_image_shuffle >= images.size())
|
if (images.size() == 0 || current_image_shuffle >= images.size())
|
||||||
{
|
{
|
||||||
@@ -164,24 +167,28 @@ std::string ShuffleImageSelector::getNextImage()
|
|||||||
std::cout << "file not found: " << filename << std::endl;
|
std::cout << "file not found: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
|
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
|
||||||
return getNextImage();
|
return getNextImage(options);
|
||||||
}
|
}
|
||||||
if (!imageValidForAspect(filename))
|
options.rotation = getImageRotation(filename);
|
||||||
|
if (!imageValidForAspect(filename, options.rotation))
|
||||||
{
|
{
|
||||||
if(debugMode)
|
if(debugMode)
|
||||||
{
|
{
|
||||||
std::cout << "image has invalid aspect: " << filename << "(images left:" << (images.size()-current_image_shuffle) << ")" << std::endl;
|
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
|
current_image_shuffle = current_image_shuffle + 1; // ignore and move to next image
|
||||||
return getNextImage();
|
return getNextImage(options);
|
||||||
}
|
}
|
||||||
std::cout << "updating image: " << filename << std::endl;
|
std::cout << "updating image: " << filename << std::endl;
|
||||||
current_image_shuffle = current_image_shuffle + 1;
|
current_image_shuffle = current_image_shuffle + 1;
|
||||||
|
options.aspect = aspect;
|
||||||
|
options.fitAspectAxisToWindow = fitAspectAxisToWindow;
|
||||||
|
pathTraverser->UpdateOptionsForImage(filename, options);
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect):
|
SortedImageSelector::SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow):
|
||||||
ImageSelector(pathTraverser, aspect),
|
ImageSelector(pathTraverser, aspect, fitAspectAxisToWindow),
|
||||||
images()
|
images()
|
||||||
{
|
{
|
||||||
srand (time(NULL));
|
srand (time(NULL));
|
||||||
@@ -203,7 +210,7 @@ bool operator<(const QString& lhs, const QString& rhs) noexcept{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SortedImageSelector::getNextImage()
|
const std::string SortedImageSelector::getNextImage(ImageOptions_t &options)
|
||||||
{
|
{
|
||||||
if (images.size() == 0)
|
if (images.size() == 0)
|
||||||
{
|
{
|
||||||
@@ -229,17 +236,21 @@ std::string SortedImageSelector::getNextImage()
|
|||||||
{
|
{
|
||||||
std::cout << "file not found: " << filename << std::endl;
|
std::cout << "file not found: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
return getNextImage();
|
return getNextImage(options);
|
||||||
}
|
}
|
||||||
if (!imageValidForAspect(filename))
|
options.rotation = getImageRotation(filename);
|
||||||
|
if (!imageValidForAspect(filename, options.rotation))
|
||||||
{
|
{
|
||||||
if(debugMode)
|
if(debugMode)
|
||||||
{
|
{
|
||||||
std::cout << "image has invalid aspect: " << filename << std::endl;
|
std::cout << "image has invalid aspect: " << filename << std::endl;
|
||||||
}
|
}
|
||||||
return getNextImage();
|
return getNextImage(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "updating image: " << filename << std::endl;
|
std::cout << "updating image: " << filename << std::endl;
|
||||||
|
options.aspect = aspect;
|
||||||
|
options.fitAspectAxisToWindow = fitAspectAxisToWindow;
|
||||||
|
pathTraverser->UpdateOptionsForImage(filename, options);
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,28 +8,36 @@
|
|||||||
class MainWindow;
|
class MainWindow;
|
||||||
class PathTraverser;
|
class PathTraverser;
|
||||||
|
|
||||||
|
struct ImageOptions_t
|
||||||
|
{
|
||||||
|
char aspect;
|
||||||
|
bool fitAspectAxisToWindow;
|
||||||
|
int rotation;
|
||||||
|
};
|
||||||
|
|
||||||
class ImageSelector
|
class ImageSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspectIn);
|
ImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspectIn, bool fitAspectAxisToWindow);
|
||||||
virtual ~ImageSelector();
|
virtual ~ImageSelector();
|
||||||
virtual std::string getNextImage() = 0;
|
virtual const std::string getNextImage(ImageOptions_t &options) = 0;
|
||||||
void setDebugMode(bool debugModeIn) { debugMode = debugModeIn;}
|
void setDebugMode(bool debugModeIn) { debugMode = debugModeIn;}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int getImageRotation(const std::string &fileName);
|
int getImageRotation(const std::string &fileName);
|
||||||
bool imageValidForAspect(const std::string &fileName);
|
bool imageValidForAspect(const std::string &fileName, const int rotation);
|
||||||
std::unique_ptr<PathTraverser>& pathTraverser;
|
std::unique_ptr<PathTraverser>& pathTraverser;
|
||||||
char aspect;
|
char aspect;
|
||||||
|
bool fitAspectAxisToWindow = false;
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RandomImageSelector : public ImageSelector
|
class RandomImageSelector : public ImageSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
|
RandomImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow);
|
||||||
virtual ~RandomImageSelector();
|
virtual ~RandomImageSelector();
|
||||||
virtual std::string getNextImage();
|
virtual const std::string getNextImage(ImageOptions_t &options);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int selectRandom(const QStringList& images) const;
|
unsigned int selectRandom(const QStringList& images) const;
|
||||||
@@ -38,9 +46,9 @@ private:
|
|||||||
class ShuffleImageSelector : public ImageSelector
|
class ShuffleImageSelector : public ImageSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
|
ShuffleImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow);
|
||||||
virtual ~ShuffleImageSelector();
|
virtual ~ShuffleImageSelector();
|
||||||
virtual std::string getNextImage();
|
virtual const std::string getNextImage(ImageOptions_t &options);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int current_image_shuffle;
|
int current_image_shuffle;
|
||||||
@@ -50,9 +58,9 @@ private:
|
|||||||
class SortedImageSelector : public ImageSelector
|
class SortedImageSelector : public ImageSelector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect);
|
SortedImageSelector(std::unique_ptr<PathTraverser>& pathTraverser, char aspect, bool fitAspectAxisToWindow);
|
||||||
virtual ~SortedImageSelector();
|
virtual ~SortedImageSelector();
|
||||||
virtual std::string getNextImage();
|
virtual const std::string getNextImage(ImageOptions_t &options);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList images;
|
QStringList images;
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ ImageSwitcher::ImageSwitcher(MainWindow& w, unsigned int timeout, std::unique_pt
|
|||||||
|
|
||||||
void ImageSwitcher::updateImage()
|
void ImageSwitcher::updateImage()
|
||||||
{
|
{
|
||||||
std::string filename(selector->getNextImage());
|
ImageOptions_t options;
|
||||||
|
std::string filename(selector->getNextImage(options));
|
||||||
if (filename == "")
|
if (filename == "")
|
||||||
{
|
{
|
||||||
window.warn("No image found.");
|
window.warn("No image found.");
|
||||||
@@ -29,7 +30,7 @@ void ImageSwitcher::updateImage()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window.setImage(filename);
|
window.setImage(filename, options);
|
||||||
timerNoContent.stop(); // we have loaded content so stop the fast polling
|
timerNoContent.stop(); // we have loaded content so stop the fast polling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/main.cpp
14
src/main.cpp
@@ -116,29 +116,29 @@ int main(int argc, char *argv[])
|
|||||||
std::unique_ptr<PathTraverser> pathTraverser;
|
std::unique_ptr<PathTraverser> pathTraverser;
|
||||||
if (!imageList.empty())
|
if (!imageList.empty())
|
||||||
{
|
{
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new ImageListPathTraverser(imageList));
|
pathTraverser = std::unique_ptr<PathTraverser>(new ImageListPathTraverser(imageList, debugMode));
|
||||||
}
|
}
|
||||||
else if (recursive)
|
else if (recursive)
|
||||||
{
|
{
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new RecursivePathTraverser(path));
|
pathTraverser = std::unique_ptr<PathTraverser>(new RecursivePathTraverser(path, debugMode));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pathTraverser = std::unique_ptr<PathTraverser>(new DefaultPathTraverser(path));
|
pathTraverser = std::unique_ptr<PathTraverser>(new DefaultPathTraverser(path, debugMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ImageSelector> selector;
|
std::unique_ptr<ImageSelector> selector;
|
||||||
if (sorted)
|
if (sorted)
|
||||||
{
|
{
|
||||||
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser, aspect));
|
selector = std::unique_ptr<ImageSelector>(new SortedImageSelector(pathTraverser, aspect, fitAspectAxisToWindow));
|
||||||
}
|
}
|
||||||
else if (shuffle)
|
else if (shuffle)
|
||||||
{
|
{
|
||||||
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser, aspect));
|
selector = std::unique_ptr<ImageSelector>(new ShuffleImageSelector(pathTraverser, aspect, fitAspectAxisToWindow));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser, aspect));
|
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser, aspect, fitAspectAxisToWindow));
|
||||||
}
|
}
|
||||||
selector->setDebugMode(debugMode);
|
selector->setDebugMode(debugMode);
|
||||||
if(debugMode)
|
if(debugMode)
|
||||||
@@ -149,9 +149,7 @@ int main(int argc, char *argv[])
|
|||||||
Overlay o(overlay);
|
Overlay o(overlay);
|
||||||
o.setDebugMode(debugMode);
|
o.setDebugMode(debugMode);
|
||||||
w.setOverlay(&o);
|
w.setOverlay(&o);
|
||||||
w.setAspect(aspect);
|
|
||||||
w.setDebugMode(debugMode);
|
w.setDebugMode(debugMode);
|
||||||
w.setFitAspectAxisToWindow(fitAspectAxisToWindow);
|
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
ImageSwitcher switcher(w, rotationSeconds * 1000, selector);
|
ImageSwitcher switcher(w, rotationSeconds * 1000, selector);
|
||||||
|
|||||||
@@ -53,47 +53,13 @@ void MainWindow::resizeEvent(QResizeEvent* event)
|
|||||||
updateImage(true);
|
updateImage(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setImage(std::string path)
|
void MainWindow::setImage(const std::string& path, const ImageOptions_t& options)
|
||||||
{
|
{
|
||||||
currentImage = path;
|
currentImage = path;
|
||||||
|
imageOptions = options;
|
||||||
updateImage(false);
|
updateImage(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::getImageRotation()
|
|
||||||
{
|
|
||||||
if (currentImage == "")
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int orientation = 0;
|
|
||||||
ExifData *exifData = exif_data_new_from_file(currentImage.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::updateImage(bool immediately)
|
void MainWindow::updateImage(bool immediately)
|
||||||
{
|
{
|
||||||
if (currentImage == "")
|
if (currentImage == "")
|
||||||
@@ -184,11 +150,6 @@ void MainWindow::setOverlay(Overlay* o)
|
|||||||
overlay = o;
|
overlay = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setAspect(char aspectIn)
|
|
||||||
{
|
|
||||||
aspect = aspectIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled)
|
QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPixmap& scaled)
|
||||||
{
|
{
|
||||||
if (scaled.width() < width()) {
|
if (scaled.width() < width()) {
|
||||||
@@ -206,21 +167,21 @@ QPixmap MainWindow::getBlurredBackground(const QPixmap& originalSize, const QPix
|
|||||||
QPixmap MainWindow::getRotatedPixmap(const QPixmap& p)
|
QPixmap MainWindow::getRotatedPixmap(const QPixmap& p)
|
||||||
{
|
{
|
||||||
QMatrix matrix;
|
QMatrix matrix;
|
||||||
matrix.rotate(getImageRotation());
|
matrix.rotate(imageOptions.rotation);
|
||||||
return p.transformed(matrix);
|
return p.transformed(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap MainWindow::getScaledPixmap(const QPixmap& p)
|
QPixmap MainWindow::getScaledPixmap(const QPixmap& p)
|
||||||
{
|
{
|
||||||
if (fitAspectAxisToWindow)
|
if (imageOptions.fitAspectAxisToWindow)
|
||||||
{
|
{
|
||||||
if ( aspect == 'p')
|
if (imageOptions.aspect == 'p')
|
||||||
{
|
{
|
||||||
// potrait mode, make height of image fit screen and crop top/bottom
|
// potrait mode, make height of image fit screen and crop top/bottom
|
||||||
QPixmap pTemp = p.scaledToHeight(height(), Qt::SmoothTransformation);
|
QPixmap pTemp = p.scaledToHeight(height(), Qt::SmoothTransformation);
|
||||||
return pTemp.copy(0,0,width(),height());
|
return pTemp.copy(0,0,width(),height());
|
||||||
}
|
}
|
||||||
else if ( aspect == 'l')
|
else if (imageOptions.aspect == 'l')
|
||||||
{
|
{
|
||||||
// landscape mode, make width of image fit screen and crop top/bottom
|
// landscape mode, make width of image fit screen and crop top/bottom
|
||||||
QPixmap pTemp = p.scaledToWidth(width(), Qt::SmoothTransformation);
|
QPixmap pTemp = p.scaledToWidth(width(), Qt::SmoothTransformation);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include "imageselector.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@@ -20,23 +21,20 @@ public:
|
|||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void resizeEvent(QResizeEvent* event);
|
void resizeEvent(QResizeEvent* event);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
void setImage(std::string path);
|
void setImage(const std::string& path, const ImageOptions_t &options);
|
||||||
void setBlurRadius(unsigned int blurRadius);
|
void setBlurRadius(unsigned int blurRadius);
|
||||||
void setBackgroundOpacity(unsigned int opacity);
|
void setBackgroundOpacity(unsigned int opacity);
|
||||||
void warn(std::string text);
|
void warn(std::string text);
|
||||||
void setOverlay(Overlay* overlay);
|
void setOverlay(Overlay* overlay);
|
||||||
void setAspect(char aspectIn);
|
|
||||||
void setDebugMode(bool debugModeIn) {debugMode = debugModeIn;}
|
void setDebugMode(bool debugModeIn) {debugMode = debugModeIn;}
|
||||||
void setFitAspectAxisToWindow(bool fitAspectAxisToWindowIn) { fitAspectAxisToWindow = fitAspectAxisToWindowIn; }
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
std::string currentImage;
|
std::string currentImage;
|
||||||
unsigned int blurRadius = 20;
|
unsigned int blurRadius = 20;
|
||||||
unsigned int backgroundOpacity = 150;
|
unsigned int backgroundOpacity = 150;
|
||||||
char aspect = 'a';
|
ImageOptions_t imageOptions;
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
bool fitAspectAxisToWindow = false;
|
|
||||||
|
|
||||||
Overlay* overlay;
|
Overlay* overlay;
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,16 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonValue>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdlib.h> /* srand, rand */
|
#include <stdlib.h> /* srand, rand */
|
||||||
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
PathTraverser::PathTraverser(const std::string path):
|
PathTraverser::PathTraverser(const std::string path, bool debugModeIn):
|
||||||
path(path)
|
path(path), debugMode(debugModeIn)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PathTraverser::~PathTraverser() {}
|
PathTraverser::~PathTraverser() {}
|
||||||
@@ -20,8 +25,38 @@ QStringList PathTraverser::getImageFormats() const {
|
|||||||
return imageFormats;
|
return imageFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursivePathTraverser::RecursivePathTraverser(const std::string path):
|
void PathTraverser::LoadOptionsForDirectory(const std::string &directoryPath, ImageOptions_t &options) const
|
||||||
PathTraverser(path)
|
{
|
||||||
|
QDir directory(directoryPath.c_str());
|
||||||
|
QString jsonFile = directory.filePath(QString("options.json"));
|
||||||
|
if(directory.exists(jsonFile))
|
||||||
|
{
|
||||||
|
if(debugMode)
|
||||||
|
{
|
||||||
|
std::cout << "Found options file" << std::endl;
|
||||||
|
}
|
||||||
|
QString val;
|
||||||
|
QFile file;
|
||||||
|
file.setFileName(jsonFile);
|
||||||
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
|
val = file.readAll();
|
||||||
|
file.close();
|
||||||
|
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
|
||||||
|
QJsonObject jsonDoc = d.object();
|
||||||
|
if(jsonDoc.contains("fitAspectAxisToWindow") && jsonDoc["fitAspectAxisToWindow"].isBool())
|
||||||
|
{
|
||||||
|
options.fitAspectAxisToWindow = jsonDoc["fitAspectAxisToWindow"].toBool();
|
||||||
|
if(debugMode)
|
||||||
|
{
|
||||||
|
std::cout << "Fit Aspect:" << options.fitAspectAxisToWindow << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// read json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecursivePathTraverser::RecursivePathTraverser(const std::string path,bool debugMode):
|
||||||
|
PathTraverser(path,debugMode)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RecursivePathTraverser::~RecursivePathTraverser() {}
|
RecursivePathTraverser::~RecursivePathTraverser() {}
|
||||||
@@ -44,8 +79,14 @@ const std::string RecursivePathTraverser::getImagePath(const std::string image)
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultPathTraverser::DefaultPathTraverser(const std::string path):
|
void RecursivePathTraverser::UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const
|
||||||
PathTraverser(path),
|
{
|
||||||
|
QDir d = QFileInfo(filename.c_str()).absoluteDir();
|
||||||
|
LoadOptionsForDirectory(d.absolutePath().toStdString(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultPathTraverser::DefaultPathTraverser(const std::string path,bool debugMode):
|
||||||
|
PathTraverser(path,debugMode),
|
||||||
directory(path.c_str())
|
directory(path.c_str())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -62,9 +103,14 @@ const std::string DefaultPathTraverser::getImagePath(const std::string image) co
|
|||||||
return directory.filePath(QString(image.c_str())).toStdString();
|
return directory.filePath(QString(image.c_str())).toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultPathTraverser::UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const
|
||||||
|
{
|
||||||
|
UNUSED(filename);
|
||||||
|
LoadOptionsForDirectory(directory.absolutePath().toStdString(), options);
|
||||||
|
}
|
||||||
|
|
||||||
ImageListPathTraverser::ImageListPathTraverser(const std::string &imageListString):
|
ImageListPathTraverser::ImageListPathTraverser(const std::string &imageListString,bool debugMode):
|
||||||
PathTraverser("")
|
PathTraverser("",debugMode)
|
||||||
{
|
{
|
||||||
QString str = QString(imageListString.c_str());
|
QString str = QString(imageListString.c_str());
|
||||||
imageList = str.split(QLatin1Char(','));
|
imageList = str.split(QLatin1Char(','));
|
||||||
@@ -81,4 +127,11 @@ QStringList ImageListPathTraverser::getImages() const
|
|||||||
const std::string ImageListPathTraverser::getImagePath(const std::string image) const
|
const std::string ImageListPathTraverser::getImagePath(const std::string image) const
|
||||||
{
|
{
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageListPathTraverser::UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const
|
||||||
|
{
|
||||||
|
// no per file options modification supported
|
||||||
|
UNUSED(filename);
|
||||||
|
UNUSED(options);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include "imageselector.h"
|
||||||
|
|
||||||
static const QStringList supportedFormats={"jpg","jpeg","png","tif","tiff"};
|
static const QStringList supportedFormats={"jpg","jpeg","png","tif","tiff"};
|
||||||
|
|
||||||
@@ -11,32 +12,37 @@ class MainWindow;
|
|||||||
class PathTraverser
|
class PathTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PathTraverser(const std::string path);
|
PathTraverser(const std::string path, bool debugModeIn);
|
||||||
virtual ~PathTraverser();
|
virtual ~PathTraverser();
|
||||||
virtual QStringList getImages() const = 0;
|
virtual QStringList getImages() const = 0;
|
||||||
virtual const std::string getImagePath(const std::string image) const = 0;
|
virtual const std::string getImagePath(const std::string image) const = 0;
|
||||||
|
virtual void UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::string path;
|
const std::string path;
|
||||||
|
bool debugMode = false;
|
||||||
QStringList getImageFormats() const;
|
QStringList getImageFormats() const;
|
||||||
|
void LoadOptionsForDirectory(const std::string &directoryPath, ImageOptions_t &options) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RecursivePathTraverser : public PathTraverser
|
class RecursivePathTraverser : public PathTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RecursivePathTraverser(const std::string path);
|
RecursivePathTraverser(const std::string path, bool debugModeIn);
|
||||||
virtual ~RecursivePathTraverser();
|
virtual ~RecursivePathTraverser();
|
||||||
QStringList getImages() const;
|
QStringList getImages() const;
|
||||||
virtual const std::string getImagePath(const std::string image) const;
|
virtual const std::string getImagePath(const std::string image) const;
|
||||||
|
virtual void UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefaultPathTraverser : public PathTraverser
|
class DefaultPathTraverser : public PathTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefaultPathTraverser(const std::string path);
|
DefaultPathTraverser(const std::string path, bool debugModeIn);
|
||||||
virtual ~DefaultPathTraverser();
|
virtual ~DefaultPathTraverser();
|
||||||
QStringList getImages() const;
|
QStringList getImages() const;
|
||||||
virtual const std::string getImagePath(const std::string image) const;
|
virtual const std::string getImagePath(const std::string image) const;
|
||||||
|
virtual void UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const;
|
||||||
private:
|
private:
|
||||||
QDir directory;
|
QDir directory;
|
||||||
};
|
};
|
||||||
@@ -44,10 +50,11 @@ class DefaultPathTraverser : public PathTraverser
|
|||||||
class ImageListPathTraverser : public PathTraverser
|
class ImageListPathTraverser : public PathTraverser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageListPathTraverser(const std::string &imageListString);
|
ImageListPathTraverser(const std::string &imageListString, bool debugModeIn);
|
||||||
virtual ~ImageListPathTraverser();
|
virtual ~ImageListPathTraverser();
|
||||||
QStringList getImages() const;
|
QStringList getImages() const;
|
||||||
virtual const std::string getImagePath(const std::string image) const;
|
virtual const std::string getImagePath(const std::string image) const;
|
||||||
|
virtual void UpdateOptionsForImage(const std::string& filename, ImageOptions_t& options) const;
|
||||||
private:
|
private:
|
||||||
QStringList imageList;
|
QStringList imageList;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user