Add generating thumbnails from cmd line

This commit is contained in:
2025-03-17 11:08:18 +01:00
parent 21675d9479
commit f30dd2a520
8 changed files with 124 additions and 27 deletions
+1
View File
@@ -55,6 +55,7 @@ set(TENMON_SRC
stfslider.cpp stfslider.h stfslider.cpp stfslider.h
stretchtoolbar.cpp stretchtoolbar.h stretchtoolbar.cpp stretchtoolbar.h
tfloat16.h tfloat16.h
thumbnailer/genthumbnail.cpp thumbnailer/genthumbnail.h
) )
qt_add_resources(TENMON_SRC resources/resources.qrc) qt_add_resources(TENMON_SRC resources/resources.qrc)
+17 -5
View File
@@ -113,6 +113,7 @@ ImageRingList::ImageRingList(Database *database, const QStringList &nameFilter,
, m_analyzeLevel(None) , m_analyzeLevel(None)
, m_database(database) , m_database(database)
, m_nameFilter(nameFilter) , m_nameFilter(nameFilter)
, m_fileSuffix(nameFilter)
{ {
connect(&m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString))); connect(&m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString)));
m_nameFilter.replaceInStrings(QRegularExpression("^"), "*."); m_nameFilter.replaceInStrings(QRegularExpression("^"), "*.");
@@ -170,8 +171,8 @@ bool ImageRingList::setDir(const QString path, const QString &currentFile, bool
}; };
scanDir(path); scanDir(path);
qDebug() << absolutePaths.size(); //qDebug() << absolutePaths.size();
setFiles(absolutePaths, m_liveMode ? absolutePaths.first() : currentFile); setFilesPrivate(absolutePaths, m_liveMode ? absolutePaths.first() : currentFile);
m_fileSystemWatcher.removePaths(m_fileSystemWatcher.directories()); m_fileSystemWatcher.removePaths(m_fileSystemWatcher.directories());
m_fileSystemWatcher.addPath(path); m_fileSystemWatcher.addPath(path);
@@ -192,6 +193,17 @@ void ImageRingList::setFile(const QString &file)
} }
} }
void ImageRingList::setFiles(QStringList files)
{
QRegularExpression reg("(" + m_fileSuffix.join("|") + ")");
files.removeIf([&reg](const QString &file){
QFileInfo info(file);
auto match = reg.match(info.suffix());
return !match.hasMatch() || !info.exists() || !info.isReadable() || !info.isFile();
});
setFilesPrivate(files);
}
ImagePtr ImageRingList::currentImage() ImagePtr ImageRingList::currentImage()
{ {
if(m_images.size()) if(m_images.size())
@@ -237,11 +249,11 @@ void ImageRingList::decrement()
void ImageRingList::setMarked() void ImageRingList::setMarked()
{ {
QStringList files = m_database->getMarkedFiles(); QStringList files = m_database->getMarkedFiles();
std::remove_if(files.begin(), files.end(), [](const QString &file){ files.removeIf([](const QString &file){
QFileInfo info(file); QFileInfo info(file);
return !info.exists() || !info.isReadable(); return !info.exists() || !info.isReadable();
}); });
setFiles(files); setFilesPrivate(files);
} }
void ImageRingList::setLiveMode(bool live) void ImageRingList::setLiveMode(bool live)
@@ -474,7 +486,7 @@ void ImageRingList::toggleSlideshow(bool start)
} }
} }
void ImageRingList::setFiles(const QStringList files, const QString &currentFile) void ImageRingList::setFilesPrivate(const QStringList files, const QString &currentFile)
{ {
m_loadPool->clear(); m_loadPool->clear();
m_thumbPool->clear(); m_thumbPool->clear();
+3 -1
View File
@@ -68,6 +68,7 @@ class ImageRingList : public QAbstractItemModel
QThreadPool *m_thumbPool; QThreadPool *m_thumbPool;
Database *m_database; Database *m_database;
QStringList m_nameFilter; QStringList m_nameFilter;
QStringList m_fileSuffix;
QTimer *m_slideShowTimer; QTimer *m_slideShowTimer;
QTimer *m_dirChangeDelay; QTimer *m_dirChangeDelay;
QString m_currentDir; QString m_currentDir;
@@ -76,6 +77,7 @@ public:
~ImageRingList() override; ~ImageRingList() override;
bool setDir(const QString path, const QString &currentFile = QString(), bool recursive = false); bool setDir(const QString path, const QString &currentFile = QString(), bool recursive = false);
void setFile(const QString &file); void setFile(const QString &file);
void setFiles(QStringList files);
ImagePtr currentImage(); ImagePtr currentImage();
void setLiveMode(bool live); void setLiveMode(bool live);
void setCalculateStats(bool stats); void setCalculateStats(bool stats);
@@ -105,7 +107,7 @@ public slots:
void decrement(); void decrement();
void setMarked(); void setMarked();
protected: protected:
void setFiles(const QStringList files, const QString &currentFile = QString()); void setFilesPrivate(const QStringList files, const QString &currentFile = QString());
QList<ImagePtr>::iterator increment(QList<ImagePtr>::iterator iter); QList<ImagePtr>::iterator increment(QList<ImagePtr>::iterator iter);
QList<ImagePtr>::iterator decrement(QList<ImagePtr>::iterator iter); QList<ImagePtr>::iterator decrement(QList<ImagePtr>::iterator iter);
signals: signals:
+51 -4
View File
@@ -2,7 +2,9 @@
#include <QApplication> #include <QApplication>
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <QTranslator> #include <QTranslator>
#include <QCommandLineParser>
#include <stdlib.h> #include <stdlib.h>
#include "thumbnailer/genthumbnail.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@@ -15,12 +17,39 @@ int main(int argc, char *argv[])
#else #else
bool useGLES = true; bool useGLES = true;
#endif #endif
QCommandLineParser cmd;
cmd.addOption({"gl", "Use desktop OpenGL. This is default on x86 and MacOS platform."});
cmd.addOption({"gles", "Use OpenGL ES. This is default on ARM platform."});
cmd.addOption({{"thumb", "thumbnail"}, "Generate thumbnail and save it to path.", "path"});
cmd.addOption({{"s", "size"}, "Size of the thumbnails in pixels (default: 128)", "size", "128"});
cmd.addPositionalArgument("file", "File to open");
cmd.addHelpOption();
QStringList cmdArgs;
for(int i = 0; i < argc; i++) for(int i = 0; i < argc; i++)
cmdArgs.append(argv[i]);
cmd.process(cmdArgs);
if(cmd.isSet("gl"))
useGLES = false;
if(cmd.isSet("gles"))
useGLES = true;
if(cmd.isSet("thumb"))
{ {
if(std::strcmp("-gl", argv[i]) == 0) QCoreApplication app(argc, argv);
useGLES = false; QStringList files = cmd.positionalArguments();
if(std::strcmp("-gles", argv[i]) == 0) if(files.size() == 0)
useGLES = true; return 1;
QString thumb = cmd.value("thumb");
int size = 128;
bool ok;
int size2 = cmd.value("s").toInt(&ok);
if(ok)
size = size2;
return generateThumbnail(files.front(), thumb, size);
} }
QSurfaceFormat format; QSurfaceFormat format;
@@ -39,6 +68,7 @@ int main(int argc, char *argv[])
} }
QSurfaceFormat::setDefaultFormat(format); QSurfaceFormat::setDefaultFormat(format);
QApplication a(argc, argv); QApplication a(argc, argv);
a.setOrganizationName("nou"); a.setOrganizationName("nou");
a.setApplicationName("Tenmon"); a.setApplicationName("Tenmon");
@@ -54,5 +84,22 @@ int main(int argc, char *argv[])
MainWindow w; MainWindow w;
w.show(); w.show();
if(!cmd.positionalArguments().isEmpty())
{
QStringList files = cmd.positionalArguments();
QStringList paths;
for(auto &arg : files)
{
QUrl url(arg);
QFileInfo info(url.isLocalFile() ? url.toLocalFile() : arg);
if(info.exists())
paths.append(info.canonicalFilePath());
}
if(paths.size() == 1)
w.loadFile(paths.front());
else if(paths.size() > 1)
w.loadFiles(paths);
}
return a.exec(); return a.exec();
} }
+5 -16
View File
@@ -327,22 +327,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
_lastDir = settings.value("mainwindow/lastdir", _lastDir).toString(); _lastDir = settings.value("mainwindow/lastdir", _lastDir).toString();
QStringList args = QCoreApplication::arguments();
args.removeFirst();
for(auto &arg : args)
{
QUrl url(arg);
QFileInfo info(url.isLocalFile() ? url.toLocalFile() : arg);
if(info.exists())
{
m_ringList->setFile(info.canonicalFilePath());
updateWindowTitle();
_lastDir = info.absoluteDir().absolutePath();
settings.setValue("mainwindow/lastdir", _lastDir);
break;
}
}
m_image->setFocus(); m_image->setFocus();
// workaround for nasty wayland backend bug https://bugreports.qt.io/browse/QTBUG-87332 // workaround for nasty wayland backend bug https://bugreports.qt.io/browse/QTBUG-87332
@@ -565,6 +549,11 @@ void MainWindow::loadFile(const QString &path)
} }
} }
void MainWindow::loadFiles(const QStringList &paths)
{
m_ringList->setFiles(paths);
}
void MainWindow::loadFile(int row) void MainWindow::loadFile(int row)
{ {
m_ringList->loadFile(row); m_ringList->loadFile(row);
+2 -1
View File
@@ -41,11 +41,12 @@ protected:
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void copyOrMove(bool copy); void copyOrMove(bool copy);
void copyOrMove(bool copy, const QString &dest); void copyOrMove(bool copy, const QString &dest);
protected slots: public slots:
void socketNotify(); void socketNotify();
void updateWindowTitle(); void updateWindowTitle();
void loadFile(); void loadFile();
void loadFile(const QString &path); void loadFile(const QString &path);
void loadFiles(const QStringList &paths);
void loadFile(int row); void loadFile(int row);
void loadDir(); void loadDir();
void indexDir(); void indexDir();
+37
View File
@@ -0,0 +1,37 @@
#include "genthumbnail.h"
#include "../rawimage.h"
#include "../loadimage.h"
int generateThumbnail(const QString &input, const QString &output, uint32_t size)
{
ImageInfoData info;
std::shared_ptr<RawImage> rawImage;
if(!loadImage(input, info, rawImage))
return 2;
if(!rawImage)
return 3;
QSize rect(rawImage->width(), rawImage->height());
rect.scale(size, size, Qt::KeepAspectRatio);
rawImage->calcStats();
rawImage->resize(rect.width(), rect.height());
if(rawImage->imageStats().m_median[0] < rawImage->norm() * 0.2f)
{
MTFParam mtfParams = rawImage->calcMTFParams(true);
rawImage->applySTF(mtfParams);
}
rawImage->convertToType(RawImage::UINT8);
QImage img;
if(rawImage->channels() == 1)
img = QImage((const uchar*)rawImage->data(), rawImage->width(), rawImage->height(), rawImage->widthBytes(), QImage::Format_Grayscale8);
else
img = QImage((const uchar*)rawImage->data(), rawImage->width(), rawImage->height(), rawImage->widthBytes(), QImage::Format_RGBA8888);
if(!img.save(output, "png"))
return 4;
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef GENTHUMBNAIL_H
#define GENTHUMBNAIL_H
#include <QString>
int generateThumbnail(const QString &input, const QString &output, uint32_t size);
#endif // GENTHUMBNAIL_H