kdeplasma-addons: load and scale images synchronously from frame applet

fixes crashes, make use of KImageIO::patterns() to support more image
formats while at it

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-03-03 18:50:04 +02:00
parent 6121a0229d
commit 87247ceaca
11 changed files with 27 additions and 222 deletions

View file

@ -4,8 +4,6 @@ set(frame_SRCS
frame.cpp
slideshow.cpp
picture.cpp
imagescaler.cpp
imageloader.cpp
configdialog.cpp
imageSettings.ui
appearanceSettings.ui

View file

@ -19,13 +19,11 @@
#include "configdialog.h"
#include <QThreadPool>
#include <KLocale>
#include <KStandardDirs>
#include <KImageIO>
#include "picture.h"
#include "imagescaler.h"
ConfigDialog::ConfigDialog(QWidget *parent)
: QObject(parent)
@ -55,6 +53,7 @@ ConfigDialog::ConfigDialog(QWidget *parent)
m_preview->setGeometry(23, 14, 151, 115);
m_preview->show();
imageUi.picRequester->setFilter(KImageIO::pattern(KImageIO::Reading));
connect(imageUi.picRequester, SIGNAL(urlSelected(KUrl)), this, SLOT(changePreview(KUrl)));
connect(imageUi.picRequester->comboBox(), SIGNAL(activated(QString)), this, SLOT(changePreview(QString)));
}
@ -125,14 +124,8 @@ KUrl ConfigDialog::currentUrl() const
void ConfigDialog::previewPicture(const QImage &image)
{
ImageScaler *scaler = new ImageScaler(image, QRect(23, 14, 151, 115).size());
connect(scaler, SIGNAL(scaled(QImage)), this, SLOT(previewScaled(QImage)));
QThreadPool::globalInstance()->start(scaler);
}
void ConfigDialog::previewScaled(const QImage &image)
{
m_preview->setPixmap(QPixmap::fromImage(image));
QImage scaledimage = image.scaled(QRect(23, 14, 151, 115).size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
m_preview->setPixmap(QPixmap::fromImage(scaledimage));
}
void ConfigDialog::changePreview(const KUrl &path)

View file

@ -66,8 +66,6 @@ private slots:
void changePreview(const QString &);
/// The image is loaded, update the preview
void pictureLoaded(QImage image);
/// The preview is scaled
void previewScaled(const QImage &);
private:
Picture *m_picture;

View file

@ -30,7 +30,6 @@
#include <QCheckBox>
#include <QFileInfo>
#include <QStandardItemModel>
#include <QThreadPool>
#include <Plasma/Containment>
#include <Plasma/Wallpaper>
@ -55,7 +54,6 @@
#include "configdialog.h"
#include "picture.h"
#include "slideshow.h"
#include "imagescaler.h"
Frame::Frame(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args),
@ -292,15 +290,7 @@ QSizeF Frame::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
void Frame::scalePictureAndUpdate()
{
QImage img = m_mySlideShow->image();
ImageScaler *scaler = new ImageScaler(img, contentSizeHint().toSize());
connect(scaler, SIGNAL(scaled(QImage)), this, SLOT(imageScaled(QImage)));
QThreadPool::globalInstance()->start(scaler);
}
void Frame::imageScaled(const QImage &img)
{
m_scaledImage = img;
m_scaledImage = m_mySlideShow->image().scaled(contentSizeHint().toSize(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
updatePicture();
}

View file

@ -76,7 +76,6 @@ private Q_SLOTS:
void updateButtons();
void delayedUpdateSize();
void scalePictureAndUpdate();
void imageScaled(const QImage &img);
void reloadImage();
protected:

View file

@ -1,46 +0,0 @@
/***************************************************************************
* Copyright 2010 by Davide Bettio <davide.bettio@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "imageloader.h"
#include <QImage>
#include <kdebug.h>
#include <kexiv2.h>
ImageLoader::ImageLoader(const QString &path)
{
m_path = path;
}
void ImageLoader::correctRotation(QImage& image, const QString &path)
{
if (!image.isNull()) {
KExiv2 exiv(path);
exiv.rotateImage(image);
}
}
void ImageLoader::run()
{
QImage img(m_path);
correctRotation(img, m_path);
emit loaded(img);
}
#include "moc_imageloader.cpp"

View file

@ -1,45 +0,0 @@
/***************************************************************************
* Copyright 2010 by Davide Bettio <davide.bettio@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef IMAGELOADER_H
#define IMAGELOADER_H
#include <QObject>
#include <QRunnable>
#include <QString>
#include <QImage>
class ImageLoader : public QObject, public QRunnable
{
Q_OBJECT
public:
ImageLoader(const QString &path);
static void correctRotation(QImage& tempImage, const QString &path);
void run();
Q_SIGNALS:
void loaded(QImage);
private:
QString m_path;
};
#endif

View file

@ -1,37 +0,0 @@
/***************************************************************************
* Copyright 2010 by Davide Bettio <davide.bettio@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#include "imagescaler.h"
#include <kdebug.h>
ImageScaler::ImageScaler(const QImage &img, QSize size)
{
m_image = img;
m_size = size;
}
void ImageScaler::run()
{
QImage img = m_image.scaled(m_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
emit scaled(img);
}
#include "moc_imagescaler.cpp"

View file

@ -1,44 +0,0 @@
/***************************************************************************
* Copyright 2010 by Davide Bettio <davide.bettio@kdemail.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
***************************************************************************/
#ifndef IMAGESCALER_H
#define IMAGESCALER_H
#include <QImage>
#include <QObject>
#include <QRunnable>
#include <QSize>
class ImageScaler : public QObject, public QRunnable
{
Q_OBJECT
public:
ImageScaler(const QImage &img, QSize size);
void run();
Q_SIGNALS:
void scaled(const QImage &image);
private:
QImage m_image;
QSize m_size;
};
#endif

View file

@ -21,7 +21,6 @@
#include "picture.h"
#include <QFile>
#include <QThreadPool>
#include <KDebug>
#include <KGlobalSettings>
@ -29,12 +28,21 @@
#include <KIO/NetAccess>
#include <KIO/Job>
#include <KStandardDirs>
#include <kexiv2.h>
#include <klocalizedstring.h>
#include <Plasma/Theme>
#include <Plasma/Svg>
#include "imageloader.h"
static QImage loadImageAndRotate(const QString &path)
{
QImage image(path);
if (!image.isNull()) {
KExiv2 exiv(path);
exiv.rotateImage(image);
}
return image;
}
Picture::Picture(QObject *parent)
: QObject(parent)
@ -77,9 +85,8 @@ QImage Picture::defaultPicture(const QString &message)
{
// Create a QImage with same axpect ratio of default svg and current pixelSize
kDebug() << "Default Image:" << m_defaultImage;
QImage image = QImage(m_defaultImage);
m_message = message;
return image;
return QImage(m_defaultImage);
}
void Picture::setPicture(const KUrl &currentUrl)
@ -93,25 +100,19 @@ void Picture::setPicture(const KUrl &currentUrl)
connect(job, SIGNAL(finished(KJob*)), this, SLOT(slotFinished(KJob*)));
emit pictureLoaded(defaultPicture(i18n("Loading image...")));
} else {
ImageLoader *loader = 0;
if (m_checkDir) {
m_message = i18nc("Info", "Dropped folder is empty. Please drop a folder with image(s)");
m_checkDir = false;
emit checkImageLoaded(loadImageAndRotate(m_defaultImage));
} else if (currentUrl.isEmpty()) {
m_message = i18nc("Info", "Put your photo here or drop a folder to start a slideshow");
kDebug() << "default image ...";
emit checkImageLoaded(loadImageAndRotate(m_defaultImage));
} else {
loader = new ImageLoader(m_currentUrl.path());
setPath(m_currentUrl.path());
m_message.clear();
emit checkImageLoaded(loadImageAndRotate(m_currentUrl.path()));
}
if (!loader) {
loader = new ImageLoader(m_defaultImage);
}
connect(loader, SIGNAL(loaded(QImage)), this, SLOT(checkImageLoaded(QImage)));
QThreadPool::globalInstance()->start(loader);
}
}
@ -134,11 +135,11 @@ void Picture::setPath(const QString &path)
void Picture::reload()
{
kDebug() << "Picture reload";
setMessage(QString());
ImageLoader *loader = new ImageLoader(m_path);
connect(loader, SIGNAL(loaded(QImage)), this, SLOT(checkImageLoaded(QImage)));
QThreadPool::globalInstance()->start(loader);
if (!m_path.isEmpty()) {
kDebug() << "Picture reload";
setMessage(QString());
emit checkImageLoaded(loadImageAndRotate(m_path));
}
}
void Picture::customizeEmptyMessage()
@ -146,9 +147,8 @@ void Picture::customizeEmptyMessage()
m_checkDir = true;
}
void Picture::slotFinished( KJob *job )
void Picture::slotFinished(KJob *job)
{
QString filename = m_currentUrl.fileName();
QString path = KStandardDirs::locateLocal("cache", "plasma-frame/" + m_currentUrl.fileName());
QImage image;
@ -164,8 +164,6 @@ void Picture::slotFinished( KJob *job )
setPath(path);
}
ImageLoader::correctRotation(image, path);
emit checkImageLoaded(image);
}

View file

@ -25,13 +25,14 @@
#include <KDebug>
#include <KRandomSequence>
#include <KImageIO>
#include "picture.h"
SlideShow::SlideShow(QObject *parent)
: QObject(parent)
{
m_filters << "*.jpeg" << "*.jpg" << "*.png" << "*.svg" << "*.svgz" << "*.bmp" << "*.tif"; // use mime types?
m_filters << KImageIO::pattern(KImageIO::Reading);
m_slideNumber = 0;
m_useRandom = false;