diff --git a/imageringlist.cpp b/imageringlist.cpp index 90dc15f..a8cd5d9 100644 --- a/imageringlist.cpp +++ b/imageringlist.cpp @@ -5,13 +5,14 @@ using namespace std; -const int DEFAULT_WIDTH = 3; +const int DEFAULT_WIDTH = 2; -Image::Image(const QString name) : +Image::Image(const QString name, ImageRingList *ringList) : m_loading(false), m_released(true), m_current(false), - m_name(name) + m_name(name), + m_ringList(ringList) { } @@ -21,7 +22,7 @@ void Image::load() { m_loading = true; m_released = false; - QThreadPool::globalInstance()->start(new LoadRunable(m_name, this)); + QThreadPool::globalInstance()->start(new LoadRunable(m_name, this, m_ringList->calculateStats())); } if(!m_loading && !m_pixmap.isNull()) emit pixmapLoaded(this); @@ -67,6 +68,7 @@ void Image::imageLoaded(QImage img, ImageInfoData info) ImageRingList::ImageRingList(QObject *parent) : QObject(parent) , m_liveMode(false) + , m_calculateStats(false) { connect(&m_fileSystemWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString))); } @@ -146,6 +148,16 @@ void ImageRingList::setLiveMode(bool live) m_liveMode = live; } +void ImageRingList::setCalculateStats(bool stats) +{ + m_calculateStats = stats; +} + +bool ImageRingList::calculateStats() const +{ + return m_calculateStats; +} + void ImageRingList::setFiles(const QStringList files, const QString ¤tFile) { QThreadPool::globalInstance()->clear(); @@ -153,7 +165,7 @@ void ImageRingList::setFiles(const QStringList files, const QString ¤tFile m_images.clear(); foreach(const QString &file, files) { - ImagePtr ptr = make_shared(file); + ImagePtr ptr = make_shared(file, this); connect(ptr.get(), SIGNAL(pixmapLoaded(Image*)), this, SLOT(imageLoaded(Image*))); m_images.append(ptr); } diff --git a/imageringlist.h b/imageringlist.h index 04832be..4d2d8aa 100644 --- a/imageringlist.h +++ b/imageringlist.h @@ -8,6 +8,8 @@ #include #include "imageinfo.h" +class ImageRingList; + class Image : public QObject { Q_OBJECT @@ -17,8 +19,9 @@ class Image : public QObject QPixmap m_pixmap; QString m_name; ImageInfoData m_info; + ImageRingList *m_ringList; public: - explicit Image(const QString name); + explicit Image(const QString name, ImageRingList *ringList); void load(); void release(); QString name() const; @@ -43,6 +46,7 @@ class ImageRingList : public QObject QList::iterator m_lastImage; QFileSystemWatcher m_fileSystemWatcher; bool m_liveMode; + bool m_calculateStats; public: explicit ImageRingList(QObject *parent = 0); ~ImageRingList(); @@ -52,6 +56,8 @@ public: void increment(); void decrement(); void setLiveMode(bool live); + void setCalculateStats(bool stats); + bool calculateStats() const; protected: void setFiles(const QStringList files, const QString ¤tFile = QString()); QList::iterator increment(QList::iterator iter); diff --git a/loadrunable.cpp b/loadrunable.cpp index 7d2ff17..bf75ca0 100644 --- a/loadrunable.cpp +++ b/loadrunable.cpp @@ -7,9 +7,10 @@ #include #include "rawimage.h" -LoadRunable::LoadRunable(const QString &file, Image *receiver) : +LoadRunable::LoadRunable(const QString &file, Image *receiver, bool stats) : m_file(file), - m_receiver(receiver) + m_receiver(receiver), + m_calculateStats(stats) { } @@ -57,7 +58,7 @@ bool loadRAW(QString path, ImageInfoData &info, RawImageAbs **image, QImage *qi out[d++] = p; } } - *image = new RawImage(w, h, out); + *image = new RawImage(rawdata.sizes.width, rawdata.sizes.height, out); } if(qimage) @@ -199,21 +200,19 @@ void LoadRunable::run() QFileInfo finfo(m_file); info.append(StringPair(QObject::tr("Filename"), finfo.fileName())); + QImage img; + RawImageAbs *rawImage = nullptr; if(m_file.endsWith(".CR2", Qt::CaseInsensitive)) { - QImage img; - loadRAW(m_file, info, nullptr, &img); - QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img), Q_ARG(ImageInfoData, info)); + loadRAW(m_file, info, m_calculateStats ? &rawImage : nullptr, &img); } else if(m_file.endsWith(".FIT", Qt::CaseInsensitive)) { - QImage img; - if(loadFITS(m_file, info, nullptr, &img)) - QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img), Q_ARG(ImageInfoData, info)); + loadFITS(m_file, info, m_calculateStats ? &rawImage : nullptr, &img); } else { - QImage img(m_file); + img = QImage(m_file); ExifData *exif = exif_data_new_from_file(m_file.toLocal8Bit().constData()); info.append(StringPair(QObject::tr("Width"), QString::number(img.width()))); info.append(StringPair(QObject::tr("Height"), QString::number(img.height()))); @@ -221,7 +220,21 @@ void LoadRunable::run() { loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_ISO_SPEED_RATINGS); loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_SHUTTER_SPEED_VALUE); + exif_data_free(exif); } - QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img), Q_ARG(ImageInfoData, info)); } + + if(rawImage) + { + uint64_t mean, median, min, max; + double stdDev; + rawImage->imageStats(&mean, &stdDev, &median, &min, &max); + info.append(StringPair(QObject::tr("Mean"), QString::number(mean))); + info.append(StringPair(QObject::tr("Standart deviation"), QString::number(stdDev))); + info.append(StringPair(QObject::tr("Median"), QString::number(median))); + info.append(StringPair(QObject::tr("Minimum"), QString::number(min))); + info.append(StringPair(QObject::tr("Maximum"), QString::number(max))); + } + + QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(QImage, img), Q_ARG(ImageInfoData, info)); } diff --git a/loadrunable.h b/loadrunable.h index 315cbcb..60724b0 100644 --- a/loadrunable.h +++ b/loadrunable.h @@ -10,8 +10,9 @@ class LoadRunable : public QRunnable { QString m_file; Image *m_receiver; + bool m_calculateStats; public: - LoadRunable(const QString &file, Image *receiver); + LoadRunable(const QString &file, Image *receiver, bool stats); void run(); }; diff --git a/mainwindow.cpp b/mainwindow.cpp index ce52e3c..dc1b16a 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -62,6 +62,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), selectMenu->addAction(tr("Unmark and next"), this, SLOT(unmarkAndNext()), Qt::Key_X); menuBar()->addMenu(selectMenu); + QMenu *statsMenu = new QMenu(tr("Statistic"), this); + QAction *statsAction = new QAction(tr("Image statistics"), this); + statsAction->setCheckable(true); + connect(statsAction, SIGNAL(toggled(bool)), this, SLOT(imageStats(bool))); + statsMenu->addAction(statsAction); + menuBar()->addMenu(statsMenu); + m_database = new Database(this); if(!m_database->init()) QMessageBox::critical(this, tr("Can't open DB"), tr("Can't open SQLITE database")); @@ -240,6 +247,11 @@ void MainWindow::liveMode(bool active) m_ringList->setLiveMode(active); } +void MainWindow::imageStats(bool imageStats) +{ + m_ringList->setCalculateStats(imageStats); +} + void MainWindow::updateWindowTitle() { ImagePtr ptr = m_ringList->currentImage(); diff --git a/mainwindow.h b/mainwindow.h index cd3747e..bfe57c5 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -38,6 +38,7 @@ protected slots: void unmarkAndNext(); void copyMarked(); void liveMode(bool active); + void imageStats(bool imageStats); }; #endif // MAINWINDOW_H