Permalink
Browse files

Move image thumbnail generation to the backend

This is an imperfect implementation and doesn't fix the other issues
around thumbnail generation. It is however a step in the right direction.
  • Loading branch information...
1 parent fabca8b commit 829e52fc4a39aa84ce225a7a062383773d11fae4 @stuartm stuartm committed Oct 30, 2013
@@ -7,7 +7,6 @@
#include "imageutils.h"
-
/** \fn ImageScanThread::ImageScanThread()
* \brief Constructor
* \return void
@@ -10,8 +10,6 @@
#include "mthread.h"
#include "imagemetadata.h"
-
-
class ImageScanThread : public MThread
{
public:
@@ -13,14 +13,13 @@
#include "imageutils.h"
#include "imagethumbgenthread.h"
-// FIXME: This should be on the backend only, not the frontend!
-
/** \fn ImageThumbGenThread::ImageThumbGenThread()
* \brief Constructor
* \return void
*/
ImageThumbGenThread::ImageThumbGenThread()
- : m_width(0), m_height(0),
+ : m_progressCount(0), m_progressTotalCount(0),
+ m_width(0), m_height(0),
m_pause(false), m_fileListSize(0)
{
QString sgName = IMAGE_STORAGE_GROUP;
@@ -87,6 +86,8 @@ void ImageThumbGenThread::run()
}
}
+ delete im;
+
m_mutex.lock();
exit = m_fileList.isEmpty();
m_mutex.unlock();
@@ -117,7 +118,6 @@ void ImageThumbGenThread::CreateImageThumbnail(ImageMetadata *im, int id)
dir.mkpath(im->m_thumbPath);
QString imageFileName = m_storageGroup.FindFile(im->m_fileName);
- LOG(VB_GENERAL, LOG_NOTICE, QString("Creating thumbnail for %1").arg(imageFileName));
// If a folder thumbnail shall be created we need to get
// the real filename from the thumbnail filename by removing
@@ -182,7 +182,10 @@ void ImageThumbGenThread::CreateImageThumbnail(ImageMetadata *im, int id)
// save the image in the thumbnail directory
if (image.save(im->m_thumbFileNameList->at(id)))
- emit ThumbnailCreated(im, id);
+ {
+ QString msg = "IMAGE_THUMB_CREATED %1";
+ gCoreContext->SendMessage(msg.arg(im->m_id));
+ }
}
@@ -225,7 +228,11 @@ void ImageThumbGenThread::CreateVideoThumbnail(ImageMetadata *im)
// save the default image in the thumbnail directory
if (image.save(im->m_thumbFileNameList->at(0)))
+ {
emit ThumbnailCreated(im, 0);
+ QString msg = "IMAGE_THUMB_CREATED %1";
+ gCoreContext->SendMessage(msg.arg(im->m_id));
+ }
}
}
@@ -239,31 +246,9 @@ void ImageThumbGenThread::CreateVideoThumbnail(ImageMetadata *im)
*/
void ImageThumbGenThread::Resize(QImage &image)
{
- // If the factor of the width to height of the image is smaller
- // than of the widget stretch the image horizontally. The image
- // will be higher then the widgets height, so it needs to be cropped.
- if ((image.width() / image.height()) < (m_width / m_height))
- {
- image = image.scaledToWidth(m_width, Qt::SmoothTransformation);
+ QSize size = QSize(m_width, m_height);
- // Copy a part of the image so that
- // the copied area has the size of the widget.
- if (image.height() > m_height)
- {
- int offset = (image.height() - m_height) / 2;
- image = image.copy(0, offset, m_width, m_height);
- }
- }
- else
- {
- image = image.scaledToHeight(m_height, Qt::SmoothTransformation);
-
- if (image.width() > m_width)
- {
- int offset = (image.width() - m_width) / 2;
- image = image.copy(offset, 0, m_width, m_height);
- }
- }
+ image = image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
@@ -314,7 +299,8 @@ void ImageThumbGenThread::RecreateThumbnail(ImageMetadata *im)
void ImageThumbGenThread::cancel()
{
m_mutex.lock();
- m_fileList.clear();
+ while (!m_fileList.isEmpty())
+ delete m_fileList.takeFirst();
m_fileListSize = 0;
m_mutex.unlock();
@@ -358,3 +344,114 @@ void ImageThumbGenThread::SetThumbnailSize(int width, int height)
if (height > 0)
m_height = height;
}
+
+
+//////////////////////////////////////////////////////////////////////////
+
+
+ImageThumbGen* ImageThumbGen::m_instance = NULL;
+
+ImageThumbGen::ImageThumbGen()
+{
+ m_imageThumbGenThread = new ImageThumbGenThread();
+}
+
+
+
+ImageThumbGen::~ImageThumbGen()
+{
+ delete m_imageThumbGenThread;
+ m_imageThumbGenThread = NULL;
+}
+
+
+
+ImageThumbGen* ImageThumbGen::getInstance()
+{
+ if (!m_instance)
+ m_instance = new ImageThumbGen();
+
+ return m_instance;
+}
+
+
+
+void ImageThumbGen::StartThumbGen()
+{
+ if (m_imageThumbGenThread && !m_imageThumbGenThread->isRunning())
+ m_imageThumbGenThread->start();
+}
+
+
+
+void ImageThumbGen::StopThumbGen()
+{
+ if (m_imageThumbGenThread && m_imageThumbGenThread->isRunning())
+ m_imageThumbGenThread->cancel();
+}
+
+
+
+bool ImageThumbGen::ThumbGenIsRunning()
+{
+ if (m_imageThumbGenThread)
+ return m_imageThumbGenThread->isRunning();
+
+ return false;
+}
+
+
+
+int ImageThumbGen::GetCurrent()
+{
+ if (m_imageThumbGenThread)
+ return m_imageThumbGenThread->m_progressCount;
+
+ return 0;
+}
+
+
+
+int ImageThumbGen::GetTotal()
+{
+ if (m_imageThumbGenThread)
+ return m_imageThumbGenThread->m_progressTotalCount;
+
+ return 0;
+}
+
+
+
+bool ImageThumbGen::AddToThumbnailList(ImageMetadata *im)
+{
+ if (!m_imageThumbGenThread)
+ return false;
+
+ m_imageThumbGenThread->AddToThumbnailList(im);
+
+ return true;
+}
+
+
+
+bool ImageThumbGen::RecreateThumbnail(ImageMetadata *im)
+{
+ if (!m_imageThumbGenThread)
+ return false;
+
+ m_imageThumbGenThread->RecreateThumbnail(im);
+
+ return true;
+}
+
+
+
+bool ImageThumbGen::SetThumbnailSize(int width, int height)
+{
+ if (!m_imageThumbGenThread)
+ return false;
+
+ m_imageThumbGenThread->SetThumbnailSize(width, height);
+
+ return true;
+}
@@ -11,12 +11,11 @@
#include "storagegroup.h"
#include "mythmetaexp.h"
-
class META_PUBLIC ImageThumbGenThread : public QThread
{
Q_OBJECT
-public:
+ public:
ImageThumbGenThread();
~ImageThumbGenThread();
@@ -27,14 +26,17 @@ class META_PUBLIC ImageThumbGenThread : public QThread
void RecreateThumbnail(ImageMetadata *);
void SetThumbnailSize(int, int);
-signals:
+ int m_progressCount;
+ int m_progressTotalCount;
+
+ signals:
void ThumbnailCreated(ImageMetadata *, int);
void UpdateThumbnailProgress(int, int);
-protected:
+ protected:
void run();
-private:
+ private:
void CreateImageThumbnail(ImageMetadata *, int);
void CreateVideoThumbnail(ImageMetadata *);
@@ -55,4 +57,29 @@ class META_PUBLIC ImageThumbGenThread : public QThread
StorageGroup m_storageGroup;
};
+class META_PUBLIC ImageThumbGen
+{
+ public:
+ static ImageThumbGen* getInstance();
+
+ void StartThumbGen();
+ void StopThumbGen();
+ bool ThumbGenIsRunning();
+
+ bool AddToThumbnailList(ImageMetadata *);
+ bool RecreateThumbnail(ImageMetadata *);
+
+ bool SetThumbnailSize(int width, int height);
+
+ int GetCurrent();
+ int GetTotal();
+
+ private:
+ ImageThumbGen();
+ ~ImageThumbGen();
+ static ImageThumbGen *m_instance;
+
+ ImageThumbGenThread *m_imageThumbGenThread;
+};
+
#endif // GALLERYTHUMBGENTHREAD_H
@@ -382,6 +382,8 @@ void ImageUtils::LoadDirectoryValues(MSqlQuery &query, ImageMetadata *dm)
// preset all directories as subfolders
dm->m_type = kSubDirectory;
+
+ LoadDirectoryThumbnailValues(dm);
}
@@ -408,6 +410,8 @@ void ImageUtils::LoadFileValues(MSqlQuery &query, ImageMetadata *dm)
dm->SetZoom( query.value(11).toInt());
dm->m_isHidden = query.value(12).toInt();
dm->SetOrientation( query.value(13).toInt(), true);
+
+ LoadFileThumbnailValues(dm);
}
@@ -829,3 +833,72 @@ bool ImageUtils::HasExifKey(Exiv2::ExifData exifData,
// list then the key has not been found
return !(it == exifData.end());
}
+
+/**
+ * \brief Gets four images from the directory from the
+ * database which will be used as a folder thumbnail
+ * \param im Holds the loaded information
+ * \return void
+ */
+void ImageUtils::LoadDirectoryThumbnailValues(ImageMetadata *im)
+{
+ // Try to get four new thumbnail filenames
+ // from the available images in this folder
+ MSqlQuery query(MSqlQuery::InitCon());
+ query.prepare("SELECT CONCAT_WS('/', path, filename), path FROM gallery_files "
+ "WHERE path = :PATH "
+ "AND type = '4' "
+ "AND hidden = '0' LIMIT :LIMIT");
+ query.bindValue(":PATH", im->m_path);
+ query.bindValue(":LIMIT", kMaxFolderThumbnails);
+
+ if (!query.exec())
+ LOG(VB_GENERAL, LOG_ERR, MythDB::DBErrorMessage(query.lastError()));
+
+ int i = 0;
+ while (query.next())
+ {
+ QString thumbFileName = QString("%1%2")
+ .arg(GetConfDir().append("/tmp/MythImage/"))
+ .arg(query.value(0).toString());
+
+ if (i >= im->m_thumbFileNameList->size())
+ break;
+
+ im->m_thumbFileNameList->replace(i, thumbFileName);
+ im->m_thumbPath = query.value(1).toString();
+ ++i;
+ }
+
+ // Set the path to the thumbnail files. As a default this will be
+ // the path ".mythtv/MythGallery" in the users home directory
+ im->m_thumbPath.prepend(GetConfDir().append("/tmp/MythImage/"));
+}
+
+
+
+/**
+ * \brief Sets the thumbnail information for a file
+ * \param im Holds the loaded information
+ * \return void
+ */
+void ImageUtils::LoadFileThumbnailValues(ImageMetadata *im)
+{
+ // Set the path to the thumbnail files. As a default this will be
+ // the path ".mythtv/MythGallery" in the users home directory
+ im->m_thumbPath = im->m_path;
+ im->m_thumbPath.prepend(GetConfDir().append("/tmp/MythImage/"));
+
+ // Create the full path and filename to the thumbnail image
+ QString thumbFileName = QString("%1%2")
+ .arg(GetConfDir().append("/tmp/MythImage/"))
+ .arg(im->m_fileName);
+
+ // If the file is a video then append a png, otherwise the preview
+ // image would not be readable due to the video file extension
+ if (im->m_type == kVideoFile)
+ thumbFileName.append(".png");
+
+ im->m_thumbFileNameList->replace(0, thumbFileName);
+}
+
@@ -67,6 +67,9 @@ class META_PUBLIC ImageUtils
void LoadDirectoryValues(MSqlQuery &, ImageMetadata *);
void LoadFileValues(MSqlQuery &, ImageMetadata *);
+ void LoadDirectoryThumbnailValues(ImageMetadata *);
+ void LoadFileThumbnailValues(ImageMetadata *);
+
bool HasExifKey(Exiv2::ExifData, const QString &);
};
Oops, something went wrong.

0 comments on commit 829e52f

Please sign in to comment.