Add text overlays

This commit is contained in:
Manuel Dewald
2021-03-04 14:40:11 +01:00
parent c84f01434e
commit d4beb46f28
7 changed files with 262 additions and 4 deletions

View File

@@ -2,6 +2,7 @@
#include "imageselector.h"
#include "imageswitcher.h"
#include "pathtraverser.h"
#include "overlay.h"
#include <QApplication>
#include <iostream>
#include <sys/file.h>
@@ -28,7 +29,8 @@ int main(int argc, char *argv[])
bool recursive = false;
bool shuffle = false;
bool sorted = false;
while ((opt = getopt(argc, argv, "b:p:t:o:rsS")) != -1) {
std::string overlay = "";
while ((opt = getopt(argc, argv, "b:p:t:o:O:rsS")) != -1) {
switch (opt) {
case 'p':
path = optarg;
@@ -52,6 +54,9 @@ int main(int argc, char *argv[])
case 'S':
sorted = true;
break;
case 'O':
overlay = optarg;
break;
default: /* '?' */
usage(argv[0]);
return 1;
@@ -88,7 +93,9 @@ int main(int argc, char *argv[])
{
selector = std::unique_ptr<ImageSelector>(new RandomImageSelector(pathTraverser));
}
std::cout << "Overlay input: " << overlay << std::endl;
Overlay o(overlay);
w.setOverlay(&o);
w.show();
ImageSwitcher switcher(w, rotationSeconds * 1000, selector);

View File

@@ -1,4 +1,5 @@
#include "mainwindow.h"
#include "overlay.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QPixmap>
@@ -9,6 +10,7 @@
#include <iostream>
#include <QPainter>
#include <QTimer>
#include <QRect>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <sstream>
@@ -99,6 +101,14 @@ void MainWindow::updateImage()
QPixmap p( currentImage.c_str() );
QPixmap rotated = getRotatedPixmap(p);
QPixmap scaled = getScaledPixmap(rotated);
if (overlay != NULL)
{
drawText(scaled, overlay->getMarginTopLeft(), overlay->getFontsizeTopLeft(), overlay->getRenderedTopLeft(currentImage).c_str(), Qt::AlignTop|Qt::AlignLeft);
drawText(scaled, overlay->getMarginTopRight(), overlay->getFontsizeTopRight(), overlay->getRenderedTopRight(currentImage).c_str(), Qt::AlignTop|Qt::AlignRight);
drawText(scaled, overlay->getMarginBottomLeft(), overlay->getFontsizeBottomLeft(), overlay->getRenderedBottomLeft(currentImage).c_str(), Qt::AlignBottom|Qt::AlignLeft);
drawText(scaled, overlay->getMarginBottomRight(), overlay->getFontsizeBottomRight(), overlay->getRenderedBottomRight(currentImage).c_str(), Qt::AlignBottom|Qt::AlignRight);
}
QLabel *label = this->findChild<QLabel*>("image");
label->setPixmap(scaled);
@@ -112,6 +122,24 @@ void MainWindow::updateImage()
update();
}
void MainWindow::drawText(QPixmap& image, int margin, int fontsize, QString text, int alignment) {
//std::cout << "text: " << text.toStdString() << " margin: " << margin << " fontsize: " << fontsize<< std::endl;
QPainter pt(&image);
pt.setPen(QPen(Qt::white));
pt.setFont(QFont("Sans", fontsize, QFont::Bold));
QRect marginRect = image.rect().adjusted(
margin,
margin,
margin*-1,
margin*-1);
pt.drawText(marginRect, alignment, text);
}
void MainWindow::setOverlay(Overlay* o)
{
overlay = o;
}
QPixmap MainWindow::getRotatedPixmap(const QPixmap& p)
{
QMatrix matrix;

View File

@@ -9,6 +9,7 @@ class MainWindow;
}
class QLabel;
class QKeyEvent;
class Overlay;
class MainWindow : public QMainWindow
{
@@ -23,6 +24,7 @@ public:
void setBlurRadius(unsigned int blurRadius);
void setBackgroundOpacity(unsigned int opacity);
void warn(std::string text);
void setOverlay(Overlay* overlay);
private:
Ui::MainWindow *ui;
@@ -31,6 +33,10 @@ private:
unsigned int blurRadius = 20;
unsigned int backgroundOpacity = 150;
Overlay* overlay;
void drawText(QPixmap& image, int margin, int fontsize, QString text, int alignment);
void updateImage();
int getImageRotation();

144
src/overlay.cpp Normal file
View File

@@ -0,0 +1,144 @@
#include "overlay.h"
#include <QString>
#include <QDateTime>
#include <libexif/exif-data.h>
#include <unistd.h>
#include <QDate>
#include <QLocale>
#include <QTime>
#include <QStringList>
#include <QRegExp>
#include <iostream>
Overlay::Overlay(const std::string overlayInput):
overlayInput(overlayInput)
{
parseInput();
}
Overlay::~Overlay() {}
void Overlay::parseInput() {
QString str = QString(overlayInput.c_str());
QStringList corners = str.split(QLatin1Char(';'));
if (corners.size() > 0) {
QStringList components = getOverlayComponents(corners[0]);
topLeftTemplate = getTemplate(components);
topLeftMargin = getMargin(components);
topLeftFontsize = getFontsize(components);
}
if (corners.size() > 1) {
QStringList components = getOverlayComponents(corners[1]);
topRightTemplate = getTemplate(components);
topRightMargin = getMargin(components);
topRightFontsize = getFontsize(components);
}
if (corners.size() > 2) {
QStringList components = getOverlayComponents(corners[2]);
bottomLeftTemplate = getTemplate(components);
bottomLeftMargin = getMargin(components);
bottomLeftFontsize = getFontsize(components);
}
if (corners.size() > 3) {
QStringList components = getOverlayComponents(corners[3]);
bottomRightTemplate = getTemplate(components);
bottomRightMargin = getMargin(components);
bottomRightFontsize = getFontsize(components);
}
}
QString Overlay::getTemplate(QStringList components){
if (components.size()>3) {
std::cout << "template: " << components[3].toStdString() << std::endl;
return components[3];
}
return "";
}
int Overlay::getMargin(QStringList components){
if (components.size()>1) {
std::cout << "margin: " << components[1].toStdString() << std::endl;
int num = components[1].toInt();
if (num > 0) {
return num;
}
}
return 20;
}
int Overlay::getFontsize(QStringList components){
if (components.size()>2) {
std::cout << "fontsize: " << components[2].toStdString() << std::endl;
int num = components[2].toInt();
if (num > 0) {
return num;
}
}
return 12;
}
QStringList Overlay::getOverlayComponents(QString corner) {
QRegExp regex("([\\d]*)\\|([\\d]*)\\|(.*)");
if (regex.exactMatch(corner)){
return regex.capturedTexts();
}
QStringList malformed;
malformed << "" << "" << "" << corner;
return malformed;
}
std::string Overlay::getRenderedTopLeft(std::string filename) {
return renderString(topLeftTemplate, filename);
}
std::string Overlay::getRenderedTopRight(std::string filename) {
return renderString(topRightTemplate, filename);
}
std::string Overlay::getRenderedBottomLeft(std::string filename) {
return renderString(bottomLeftTemplate, filename);
}
std::string Overlay::getRenderedBottomRight(std::string filename) {
return renderString(bottomRightTemplate, filename);
}
int Overlay::getMarginTopLeft() {return topLeftMargin;}
int Overlay::getFontsizeTopLeft() {return topLeftFontsize;}
int Overlay::getMarginTopRight() {return topRightMargin;}
int Overlay::getFontsizeTopRight() {return topRightFontsize;}
int Overlay::getMarginBottomLeft() {return bottomLeftMargin;}
int Overlay::getFontsizeBottomLeft() {return bottomLeftFontsize;}
int Overlay::getMarginBottomRight() {return bottomRightMargin;}
int Overlay::getFontsizeBottomRight() {return bottomRightFontsize;}
std::string Overlay::renderString(QString overlayTemplate, std::string filename) {
QString result = overlayTemplate;
result.replace("<datetime>", QLocale::system().toString(QDateTime::currentDateTime()));
result.replace("<date>", QLocale::system().toString(QDate::currentDate()));
result.replace("<time>", QTime::currentTime().toString("hh:mm"));
result.replace("<filename>", filename.c_str());
result.replace("<exifdatetime>", getExifDate(filename));
return result.toStdString();
}
QString Overlay::getExifDate(std::string filename) {
QString dateTime;
ExifData *exifData = exif_data_new_from_file(filename.c_str());
if (exifData)
{
ExifEntry *exifEntry = exif_data_get_entry(exifData, EXIF_TAG_DATE_TIME_ORIGINAL);
if (exifEntry)
{
char buf[2048];
dateTime = exif_entry_get_value(exifEntry, buf, sizeof(buf));
}
exif_data_free(exifData);
QString exifDateFormat = "yyyy:MM:dd hh:mm:ss";
QDateTime exifDateTime = QDateTime::fromString(dateTime, exifDateFormat);
return QLocale::system().toString(exifDateTime);
}
return dateTime;
}

60
src/overlay.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef OVERLAY_H
#define OVERLAY_H
#include <iostream>
#include <QDir>
#include <iostream>
#include <QString>
#include <QStringList>
class MainWindow;
class Overlay
{
public:
Overlay(const std::string path);
virtual ~Overlay();
std::string getRenderedTopLeft(std::string filename);
std::string getRenderedTopRight(std::string filename);
std::string getRenderedBottomLeft(std::string filename);
std::string getRenderedBottomRight(std::string filename);
int getMarginTopLeft();
int getFontsizeTopLeft();
int getMarginTopRight();
int getFontsizeTopRight();
int getMarginBottomLeft();
int getFontsizeBottomLeft();
int getMarginBottomRight();
int getFontsizeBottomRight();
private:
const std::string overlayInput;
int margin;
int fontsize;
QString topLeftTemplate;
QString topRightTemplate;
QString bottomLeftTemplate;
QString bottomRightTemplate;
int topLeftMargin;
int topRightMargin;
int bottomLeftMargin;
int bottomRightMargin;
int topLeftFontsize;
int topRightFontsize;
int bottomLeftFontsize;
int bottomRightFontsize;
QStringList getOverlayComponents(QString corner);
int getMargin(QStringList components);
int getFontsize(QStringList components);
QString getTemplate(QStringList components);
QString getExifDate(std::string filename);
void parseInput();
std::string renderString(QString overlayTemplate, std::string filename);
};
#endif

View File

@@ -32,12 +32,14 @@ SOURCES += \
mainwindow.cpp \
imageswitcher.cpp \
pathtraverser.cpp \
overlay.cpp \
imageselector.cpp
HEADERS += \
mainwindow.h \
imageselector.h \
pathtraverser.h \
overlay.h \
imageswitcher.h
FORMS += \