Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe3e5f66be | |||
| 6fd17fbdf5 | |||
| f30dd2a520 | |||
| 21675d9479 |
@@ -55,6 +55,7 @@ set(TENMON_SRC
|
||||
stfslider.cpp stfslider.h
|
||||
stretchtoolbar.cpp stretchtoolbar.h
|
||||
tfloat16.h
|
||||
thumbnailer/genthumbnail.cpp thumbnailer/genthumbnail.h
|
||||
)
|
||||
|
||||
qt_add_resources(TENMON_SRC resources/resources.qrc)
|
||||
|
||||
+3
-2
@@ -67,7 +67,8 @@ void BatchProcessing::scanScriptDir()
|
||||
if(idx>=0)_ui->scriptsList->setCurrentRow(idx);
|
||||
}
|
||||
|
||||
BatchProcessing::BatchProcessing(QWidget *parent) : QDialog(parent)
|
||||
BatchProcessing::BatchProcessing(Database *database, QWidget *parent) : QDialog(parent)
|
||||
, _database(database)
|
||||
{
|
||||
_ui = new Ui::BatchProcessing;
|
||||
_ui->setupUi(this);
|
||||
@@ -200,7 +201,7 @@ void BatchProcessing::runScript()
|
||||
auto selectedItems = _ui->scriptsList->selectedItems();
|
||||
if(selectedItems.size())
|
||||
{
|
||||
_engineThread = new Script::ScriptEngineThread(this);
|
||||
_engineThread = new Script::ScriptEngineThread(_database, this);
|
||||
connect(_engineThread, &Script::ScriptEngineThread::newMessage, this, &BatchProcessing::newMessage);
|
||||
connect(_engineThread, &Script::ScriptEngineThread::finished, this, &BatchProcessing::scriptFinished);
|
||||
QStringList paths;
|
||||
|
||||
+4
-1
@@ -7,6 +7,8 @@
|
||||
|
||||
namespace Ui { class BatchProcessing; }
|
||||
|
||||
class Database;
|
||||
|
||||
class BatchProcessing : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -15,10 +17,11 @@ class BatchProcessing : public QDialog
|
||||
QFileSystemWatcher _fileWatcher;
|
||||
Script::ScriptEngineThread *_engineThread = nullptr;
|
||||
QColor _textColor;
|
||||
Database *_database;
|
||||
private slots:
|
||||
void scanScriptDir();
|
||||
public:
|
||||
explicit BatchProcessing(QWidget *parent = nullptr);
|
||||
explicit BatchProcessing(Database *database, QWidget *parent = nullptr);
|
||||
~BatchProcessing();
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
+12
-5
@@ -15,7 +15,7 @@ bool Database::init(const QLatin1String &connectionName)
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
QDir dir(path);
|
||||
|
||||
QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
||||
database = QSqlDatabase::addDatabase("QSQLITE", connectionName);
|
||||
|
||||
if(!dir.mkpath("."))
|
||||
return false;
|
||||
@@ -27,7 +27,7 @@ bool Database::init(const QLatin1String &connectionName)
|
||||
{
|
||||
QSqlQuery query(database);
|
||||
query.exec("PRAGMA foreign_keys = ON");
|
||||
int version = checkVersion();
|
||||
int version = checkVersion(database);
|
||||
if(version == 0)
|
||||
{
|
||||
query.exec("PRAGMA user_version = 1");
|
||||
@@ -76,6 +76,14 @@ bool Database::init(const QLatin1String &connectionName)
|
||||
}
|
||||
qDebug() << error.text();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Failed to open database" << connectionName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Database is invalid";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -146,10 +154,9 @@ bool Database::checkError(QSqlQuery &query)
|
||||
}
|
||||
}
|
||||
|
||||
int Database::checkVersion()
|
||||
int Database::checkVersion(QSqlDatabase &db)
|
||||
{
|
||||
QSqlDatabase db = QSqlDatabase::database();
|
||||
QSqlQuery query("PRAGMA user_version");
|
||||
QSqlQuery query("PRAGMA user_version", db);
|
||||
if(query.next())
|
||||
return query.value(0).toInt();
|
||||
return -1;
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
class Database : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QSqlDatabase database;
|
||||
QSqlQuery m_markQuery;
|
||||
QSqlQuery m_unmarkQuery;
|
||||
QSqlQuery m_isMarkedQuery;
|
||||
@@ -40,7 +41,7 @@ protected:
|
||||
bool indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs);
|
||||
bool indexFile(const QFileInfo &file);
|
||||
bool checkError(QSqlQuery &query);
|
||||
int checkVersion();
|
||||
int checkVersion(QSqlDatabase &db);
|
||||
signals:
|
||||
void databaseChanged();
|
||||
};
|
||||
|
||||
+17
-5
@@ -113,6 +113,7 @@ ImageRingList::ImageRingList(Database *database, const QStringList &nameFilter,
|
||||
, m_analyzeLevel(None)
|
||||
, m_database(database)
|
||||
, m_nameFilter(nameFilter)
|
||||
, m_fileSuffix(nameFilter)
|
||||
{
|
||||
connect(&m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString)));
|
||||
m_nameFilter.replaceInStrings(QRegularExpression("^"), "*.");
|
||||
@@ -170,8 +171,8 @@ bool ImageRingList::setDir(const QString path, const QString ¤tFile, bool
|
||||
};
|
||||
|
||||
scanDir(path);
|
||||
qDebug() << absolutePaths.size();
|
||||
setFiles(absolutePaths, m_liveMode ? absolutePaths.first() : currentFile);
|
||||
//qDebug() << absolutePaths.size();
|
||||
setFilesPrivate(absolutePaths, m_liveMode ? absolutePaths.first() : currentFile);
|
||||
|
||||
m_fileSystemWatcher.removePaths(m_fileSystemWatcher.directories());
|
||||
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([®](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()
|
||||
{
|
||||
if(m_images.size())
|
||||
@@ -237,11 +249,11 @@ void ImageRingList::decrement()
|
||||
void ImageRingList::setMarked()
|
||||
{
|
||||
QStringList files = m_database->getMarkedFiles();
|
||||
std::remove_if(files.begin(), files.end(), [](const QString &file){
|
||||
files.removeIf([](const QString &file){
|
||||
QFileInfo info(file);
|
||||
return !info.exists() || !info.isReadable();
|
||||
});
|
||||
setFiles(files);
|
||||
setFilesPrivate(files);
|
||||
}
|
||||
|
||||
void ImageRingList::setLiveMode(bool live)
|
||||
@@ -474,7 +486,7 @@ void ImageRingList::toggleSlideshow(bool start)
|
||||
}
|
||||
}
|
||||
|
||||
void ImageRingList::setFiles(const QStringList files, const QString ¤tFile)
|
||||
void ImageRingList::setFilesPrivate(const QStringList files, const QString ¤tFile)
|
||||
{
|
||||
m_loadPool->clear();
|
||||
m_thumbPool->clear();
|
||||
|
||||
+3
-1
@@ -68,6 +68,7 @@ class ImageRingList : public QAbstractItemModel
|
||||
QThreadPool *m_thumbPool;
|
||||
Database *m_database;
|
||||
QStringList m_nameFilter;
|
||||
QStringList m_fileSuffix;
|
||||
QTimer *m_slideShowTimer;
|
||||
QTimer *m_dirChangeDelay;
|
||||
QString m_currentDir;
|
||||
@@ -76,6 +77,7 @@ public:
|
||||
~ImageRingList() override;
|
||||
bool setDir(const QString path, const QString ¤tFile = QString(), bool recursive = false);
|
||||
void setFile(const QString &file);
|
||||
void setFiles(QStringList files);
|
||||
ImagePtr currentImage();
|
||||
void setLiveMode(bool live);
|
||||
void setCalculateStats(bool stats);
|
||||
@@ -105,7 +107,7 @@ public slots:
|
||||
void decrement();
|
||||
void setMarked();
|
||||
protected:
|
||||
void setFiles(const QStringList files, const QString ¤tFile = QString());
|
||||
void setFilesPrivate(const QStringList files, const QString ¤tFile = QString());
|
||||
QList<ImagePtr>::iterator increment(QList<ImagePtr>::iterator iter);
|
||||
QList<ImagePtr>::iterator decrement(QList<ImagePtr>::iterator iter);
|
||||
signals:
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#include <QApplication>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QTranslator>
|
||||
#include <QCommandLineParser>
|
||||
#include <stdlib.h>
|
||||
#include "thumbnailer/genthumbnail.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -15,12 +17,39 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
bool useGLES = true;
|
||||
#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++)
|
||||
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)
|
||||
useGLES = false;
|
||||
if(std::strcmp("-gles", argv[i]) == 0)
|
||||
useGLES = true;
|
||||
QCoreApplication app(argc, argv);
|
||||
QStringList files = cmd.positionalArguments();
|
||||
if(files.size() == 0)
|
||||
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;
|
||||
@@ -39,6 +68,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
|
||||
|
||||
QApplication a(argc, argv);
|
||||
a.setOrganizationName("nou");
|
||||
a.setApplicationName("Tenmon");
|
||||
@@ -54,5 +84,22 @@ int main(int argc, char *argv[])
|
||||
MainWindow w;
|
||||
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();
|
||||
}
|
||||
|
||||
+6
-17
@@ -167,7 +167,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
fileMenu->addAction(tr("Reindex files"), this, SLOT(reindex()));
|
||||
fileMenu->addAction(tr("Export database to CSV"), this, &MainWindow::exportCSV);
|
||||
fileMenu->addAction(tr("Batch processing"), Qt::Key_B | Qt::CTRL, [this](){
|
||||
BatchProcessing *batchProcessing = new BatchProcessing(this);
|
||||
BatchProcessing *batchProcessing = new BatchProcessing(m_database, this);
|
||||
batchProcessing->exec();
|
||||
delete batchProcessing;
|
||||
});
|
||||
@@ -327,22 +327,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
|
||||
_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();
|
||||
|
||||
// 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)
|
||||
{
|
||||
m_ringList->loadFile(row);
|
||||
|
||||
+2
-1
@@ -41,11 +41,12 @@ protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void copyOrMove(bool copy);
|
||||
void copyOrMove(bool copy, const QString &dest);
|
||||
protected slots:
|
||||
public slots:
|
||||
void socketNotify();
|
||||
void updateWindowTitle();
|
||||
void loadFile();
|
||||
void loadFile(const QString &path);
|
||||
void loadFiles(const QStringList &paths);
|
||||
void loadFile(int row);
|
||||
void loadDir();
|
||||
void indexDir();
|
||||
|
||||
+13
-9
@@ -17,9 +17,9 @@
|
||||
namespace Script
|
||||
{
|
||||
|
||||
ScriptEngine::ScriptEngine(BatchProcessing *parent)
|
||||
ScriptEngine::ScriptEngine(Database *database, BatchProcessing *parent)
|
||||
: _jsEngine(new QJSEngine(this))
|
||||
, _database(new Database(this))
|
||||
, _database(database)
|
||||
, _parent(parent)
|
||||
, _pool(new QThreadPool(this))
|
||||
{
|
||||
@@ -27,7 +27,6 @@ ScriptEngine::ScriptEngine(BatchProcessing *parent)
|
||||
_jsEngine->globalObject().setProperty("core", core);
|
||||
QJSValue fitsRecordObject = _jsEngine->newQMetaObject(&FITSRecordModify::staticMetaObject);
|
||||
_jsEngine->globalObject().setProperty("FITSRecordModify", fitsRecordObject);
|
||||
_database->init(QLatin1String("scriptengine"));
|
||||
_semaphore.release(_pool->maxThreadCount());
|
||||
_pool->setThreadPriority(QThread::LowPriority);
|
||||
|
||||
@@ -73,17 +72,22 @@ void ScriptEngine::log(const QString &message)
|
||||
|
||||
void ScriptEngine::mark(File *file)
|
||||
{
|
||||
_database->mark(file->absoluteFilePath());
|
||||
QString path = file->absoluteFilePath();
|
||||
QMetaObject::invokeMethod(_database, [this, path](){ _database->mark(path); }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void ScriptEngine::unmark(File *file)
|
||||
{
|
||||
_database->unmark(file->absoluteFilePath());
|
||||
QString path = file->absoluteFilePath();
|
||||
QMetaObject::invokeMethod(_database, [this, path](){ _database->unmark(path); }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
bool ScriptEngine::isMarked(const File *file) const
|
||||
bool ScriptEngine::isMarked(const File *file)
|
||||
{
|
||||
return _database->isMarked(file->absoluteFilePath());
|
||||
bool ret;
|
||||
QString path = file->absoluteFilePath();
|
||||
QMetaObject::invokeMethod(_database, [this, path](){ return _database->isMarked(path); }, Qt::BlockingQueuedConnection, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ScriptEngine::setMaxThread(int maxthread)
|
||||
@@ -765,11 +769,11 @@ QJSValue File::extractStars(bool hfr)
|
||||
}
|
||||
#endif // PLATESOLVER
|
||||
|
||||
ScriptEngineThread::ScriptEngineThread(BatchProcessing *parent) : QObject(parent)
|
||||
ScriptEngineThread::ScriptEngineThread(Database *database, BatchProcessing *parent) : QObject(parent)
|
||||
{
|
||||
_thread = new QThread();
|
||||
_thread->setObjectName("ScriptEngine");
|
||||
_engine = new ScriptEngine(parent);
|
||||
_engine = new ScriptEngine(database, parent);
|
||||
_engine->moveToThread(_thread);
|
||||
connect(_engine, &ScriptEngine::finished, _thread, &QThread::quit);
|
||||
connect(_engine, &ScriptEngine::newMessage, this, &ScriptEngineThread::newMessage);
|
||||
|
||||
+3
-3
@@ -31,7 +31,7 @@ class ScriptEngine : public QObject
|
||||
QList<QPair<QString, QString>> _paths;
|
||||
Solver *_solver = nullptr;
|
||||
public:
|
||||
explicit ScriptEngine(BatchProcessing *parent = nullptr);
|
||||
explicit ScriptEngine(Database *database, BatchProcessing *parent = nullptr);
|
||||
void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
|
||||
void reportError(const QString &message);
|
||||
const QString& outputDir() const;
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
Q_INVOKABLE void log(const QString &message);
|
||||
Q_INVOKABLE void mark(File *file);
|
||||
Q_INVOKABLE void unmark(File *file);
|
||||
Q_INVOKABLE bool isMarked(const File *file) const;
|
||||
Q_INVOKABLE bool isMarked(const File *file);
|
||||
Q_INVOKABLE void setMaxThread(int maxthread);
|
||||
Q_INVOKABLE void sync();
|
||||
Q_INVOKABLE QJSValue getString(const QString &label = QString(), const QString &text = QString()) const;
|
||||
@@ -71,7 +71,7 @@ class ScriptEngineThread : public QObject
|
||||
QThread *_thread;
|
||||
ScriptEngine *_engine;
|
||||
public:
|
||||
ScriptEngineThread(BatchProcessing *parent = nullptr);
|
||||
ScriptEngineThread(Database *database, BatchProcessing *parent = nullptr);
|
||||
~ScriptEngineThread();
|
||||
void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
|
||||
void start();
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
#include <QLabel>
|
||||
#include <QSettings>
|
||||
#include <QApplication>
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QPushButton>
|
||||
#include "rawimage.h"
|
||||
|
||||
extern int DEFAULT_WIDTH;
|
||||
@@ -80,6 +86,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
|
||||
m_bestFit->setToolTip(tr("Set Best Fit zoom level when opening new image."));
|
||||
m_bestFit->setChecked(BESTFIT);
|
||||
|
||||
|
||||
layout->addRow(tr("Image preload count"), m_preloadImages);
|
||||
layout->addRow(tr("Thumbnails size"), m_thumSize);
|
||||
layout->addRow(tr("Saturation"), m_saturation);
|
||||
@@ -88,8 +95,16 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
|
||||
layout->addRow(m_qualityThumbnail);
|
||||
layout->addRow(m_useNativeDialog);
|
||||
layout->addRow(m_bestFit);
|
||||
|
||||
#ifdef Q_OS_WIN64
|
||||
QPushButton *installThumbnailer = new QPushButton(tr("Install"), this);
|
||||
installThumbnailer->setToolTip(tr("This will install thumnail generation for FITS and XISF files in File Explorer"));
|
||||
connect(installThumbnailer, &QPushButton::clicked, this, &SettingsDialog::installThumbnailer);
|
||||
layout->addRow(tr("Install thumbnailer"), installThumbnailer);
|
||||
#endif
|
||||
//layout->addRow(new QLabel(tr("Changes in settings will take effect after program restart.")));
|
||||
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
@@ -123,6 +138,25 @@ bool SettingsDialog::loadThumbsizes()
|
||||
return OLD_THUMB_SIZE != THUMB_SIZE;
|
||||
}
|
||||
|
||||
void SettingsDialog::installThumbnailer()
|
||||
{
|
||||
#ifdef Q_OS_WIN64
|
||||
QString path = QCoreApplication::instance()->applicationDirPath() + "/tenmonthumbnailer.dll";
|
||||
if(!QFileInfo::exists(path))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Missing dll"), tr("Can't find ") + path);
|
||||
return;
|
||||
}
|
||||
|
||||
QProcess regsvr;
|
||||
int ret = regsvr.execute("regsvr32.exe", {"/s", path});
|
||||
if(ret)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to register thumbnailer. %1").arg(ret));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SettingsDialog::saveSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
@@ -13,6 +13,8 @@ public:
|
||||
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||
static void loadSettings();
|
||||
static bool loadThumbsizes();
|
||||
public slots:
|
||||
void installThumbnailer();
|
||||
signals:
|
||||
void preloadChanged(int witdth);
|
||||
private:
|
||||
|
||||
@@ -58,6 +58,15 @@
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="20250318" date="2025-03-18">
|
||||
<description>
|
||||
<ul>
|
||||
<li>Fix OpenGL ES drawings</li>
|
||||
<li>Fix mark/unmark files from script</li>
|
||||
<li>Fix stretching of float images with values outside of 0-1 range</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="20250302" date="2025-03-02">
|
||||
<description>
|
||||
<ul>
|
||||
|
||||
+1
-1
@@ -208,7 +208,7 @@ STDAPI DllRegisterServer()
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// This tells the shell to invalidate the thumbnail cache. This is important because any .recipe files
|
||||
// This tells the shell to invalidate the thumbnail cache. This is important because any .xisf files
|
||||
// viewed before registering this handler would otherwise show cached blank thumbnails.
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -9,15 +9,15 @@ void RawImageToHTBITMAP(std::shared_ptr<RawImage> &rawImage, HBITMAP *hbmp, UINT
|
||||
{
|
||||
rawImage->calcStats();
|
||||
|
||||
DWORD thre = 20;
|
||||
DWORD thre = 10;
|
||||
DWORD dataSize = 4;
|
||||
HRESULT hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\nou\\Tenmon\\settings", L"thumbnailstretchthreshold", RRF_RT_DWORD, NULL, &thre, &dataSize));
|
||||
//HRESULT hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_CURRENT_USER, L"SOFTWARE\\nou\\Tenmon\\settings", L"thumbnailstretchthreshold", RRF_RT_DWORD, NULL, &thre, &dataSize));
|
||||
|
||||
float thref = 0.2f;
|
||||
if(hr == S_OK)
|
||||
thref = thre / 100.0f;
|
||||
float thref = 0.1f;
|
||||
/*if(hr == S_OK)
|
||||
thref = thre / 100.0f;*/
|
||||
|
||||
if(rawImage->imageStats().m_median[0] < rawImage->norm() * thref)
|
||||
if(rawImage->imageStats().m_mean[0] < rawImage->norm() * thref)
|
||||
{
|
||||
//OutputDebugStringA("Stretch image");
|
||||
MTFParam params = rawImage->calcMTFParams();
|
||||
|
||||
Reference in New Issue
Block a user