caesium/compressionthread.cpp

342 lines
13 KiB
C++
Raw Permalink Normal View History

/*******************************************************************************
#
# Copyright (C) 2010-2013 Matteo Paonessa <matteo.paonessa@gmail.com>
# 2021 Gary Wang <wzc782970009@gmail.com>
#
# This file is part of the Caesium distribution.
#
# Caesium 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.
#
# Caesium 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 Caesium; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
#
# Author: Matteo Paonessa <matteo.paonessa@gmail.com>
#
# ******************************************************************************/
#include "compressionthread.h"
#include "caesium.h"
#include "ui_caesium.h"
#include "global.h"
#include "imageresize.h"
#include <QSettings>
#include <QFile>
#include <QMessageBox>
#include <QDebug>
#include <QProgressDialog>
2021-10-04 15:24:39 +08:00
#include <QFileInfo>
#include <QDir>
#include <iostream>
CompressionThread::CompressionThread(QStringList list, QString orig_dir, QString dir, QString format, QString suffix, QStringList quality, bool checked, QList<int> w, QList<int> h, bool fixed, bool keepARatio, bool notEnlarge, bool resize, bool structure,
QObject *parent)
: QThread(parent)
{
t_list = list;
t_dir = dir;
t_format = format;
t_suffix = suffix;
t_quality = quality;
t_checked = checked;
t_w = w;
t_h = h;
t_fixed = fixed;
t_keepARatio = keepARatio;
t_notEnlarge = notEnlarge;
t_resize = resize;
t_structure = structure;
t_orig_dir = orig_dir;
2021-10-04 15:24:39 +08:00
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
settings.setIniCodec("UTF-8");
2021-10-04 15:24:39 +08:00
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
}
QString t_getRatio(int origSize, int newSize)
{
int ratio = newSize * 100 / origSize;
if (ratio <= 100)
{
return QString::number(ratio - 100) + " %";
}
else
{
return "+" + QString::number(ratio - 100) + " %";
}
}
void CompressionThread::run()
{
bool sameFormat = false;
QString t_dir_original = t_dir;
if (t_format == "null")
{
sameFormat = true;
}
bool no_enlarge = settings.value("Preferences/noenlarge").value<bool>();
if (no_enlarge)
{
CompressionThread::noEnlarge();
return;
}
ImageResize imgResize;
for (int i = 0; i < t_list.count(); i++)
{
QString right_dir = "";
QString originalQuality = t_quality.at(i);
QFileInfo info(t_list.at(i));
if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
continue;
}
if (QFile::exists(t_list.at(i)))
{
if (sameFormat)
{
t_format = info.suffix();
if (!isJpegSuffix(t_format))
{
t_quality.replace(i, "1");
}
else
{
t_quality.replace(i, originalQuality);
}
}
int old_size = info.size();
emit processingIcon(i, info.fileName());
QImage image(t_list.at(i));
if (t_resize && t_fixed)
{
image = imgResize.fixedResize(image, t_w.at(i), t_h.at(i), t_keepARatio, t_notEnlarge);
}
else if (t_resize && t_fixed == false)
{
if (t_w.at(i) == -1 && t_h.at(i) == -1)
{
t_w.replace(i, image.width());
t_h.replace(i, image.height());
}
image = imgResize.pergentageResize(image, t_w.at(i), t_h.at(i));
}
if (t_checked)
{
t_dir = info.path();
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else if (t_structure)
{
right_dir = info.path().remove(t_orig_dir.replace('\\', '/'), Qt::CaseSensitive);
right_dir = t_dir_original + right_dir;
right_dir.replace('\\', '/');
t_dir = right_dir;
if (!QDir(t_dir).exists())
{
if (!QDir().mkpath(t_dir))
{
emit errorMessageBox();
return;
}
}
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else
{
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
if (settings.value("Preferences/exif").value<bool>() && t_format.toLower() == "jpg")
{
QString destImagePath = t_dir + QDir::separator() + info.completeBaseName() + t_suffix;
copyExif(t_list.at(i), destImagePath);
}
QFile newImage(t_dir + "/" + info.completeBaseName() + t_suffix);
QFileInfo newInfo;
if (QFile::exists(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format))
{
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
newImage.rename(t_dir + "/" + info.completeBaseName() + t_suffix, t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
newInfo.setFile(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
int size = newInfo.size();
QString ratio = t_getRatio(old_size, newInfo.size());
if(settings.value("Preferences/keepdate").value<bool>())
{
CompressionThread::keepDate(t_list.at(i), newInfo.filePath());
}
emit updateUI(i + 1, size, ratio);
}
else
{
emit updateUI(i + 1, -1, "0%");
}
}
exit();
}
void CompressionThread::noEnlarge()
{
ImageResize imgResize;
QString t_dir_original = t_dir;
bool sameFormat = false;
if (t_format == "null")
{
sameFormat = true;
}
for (int i = 0; i < t_list.count(); i++)
{
QString originalQuality = t_quality.at(i);
QString right_dir = "";
QFileInfo info(t_list.at(i));
if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
continue;
}
if (QFile::exists(t_list.at(i)))
{
if (sameFormat)
{
t_format = info.suffix();
if (!isJpegSuffix(t_format))
{
t_quality.replace(i, "1");
}
else
{
t_quality.replace(i, originalQuality);
}
}
int old_size = info.size();
emit processingIcon(i, info.fileName());
QImage image(t_list.at(i));
if (t_resize && t_fixed)
{
image = imgResize.fixedResize(image, t_w.at(i), t_h.at(i), t_keepARatio, t_notEnlarge);
}
else if (t_resize && t_fixed == false)
{
image = imgResize.pergentageResize(image, t_w.at(i), t_h.at(i));
}
if (t_checked)
{
t_dir = info.path();
image.save(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else if (t_structure)
{
right_dir = info.path().remove(t_orig_dir.replace('\\', '/'), Qt::CaseSensitive);
right_dir = t_dir_original + right_dir;
right_dir.replace('\\', '/');
t_dir = right_dir;
if (!QDir(t_dir).exists())
{
if (!QDir().mkdir(t_dir))
{
emit errorMessageBox();
return;
}
}
image.save(t_dir + "/" + info.completeBaseName() + t_suffix, t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
else
{
image.save(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_format.toLatin1(), t_quality.at(i).toInt());
/*if (t_format.toLatin1().toLower() == "png" && settings.value("Preferences/pngcompression").value<bool>())
{
CompressionThread::optimizePNG(t_dir + "/" + info.completeBaseName() + t_suffix, settings.value("Preferences/pnglevel").value<int>());
}*/
}
if (settings.value("Preferences/exif").value<bool>() && t_format.toLower() == "jpg")
{
QString destImagePath = t_dir + QDir::separator() + info.completeBaseName() + t_suffix + "." + t_format;
copyExif(t_list.at(i), destImagePath);
}
QFileInfo newInfo(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd");
int size = newInfo.size();
QString ratio = t_getRatio(old_size, newInfo.size());
if (newInfo.size() > info.size())
{
size *= -1;
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd");
}
else
{
QFile::remove(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
QFile::rename(t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format + ".ckd", t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
if(settings.value("Preferences/keepdate").value<bool>())
{
CompressionThread::keepDate(t_list.at(i), t_dir + "/" + info.completeBaseName() + t_suffix + "." + t_format);
}
emit updateUI(i + 1, size, ratio);
}
else if (info.size() == 0)
{
emit updateUI(i + 1, 0, "0%");
}
else
{
emit updateUI(i + 1, -1, "0%");
}
}
}
void CompressionThread::keepDate(const QString & orig, const QString & dest)
{
QFile origFile(orig), destFile(dest);
destFile.open(QIODevice::Append);
destFile.setFileTime(origFile.fileTime(QFileDevice::FileAccessTime), QFileDevice::FileAccessTime);
destFile.setFileTime(origFile.fileTime(QFileDevice::FileBirthTime), QFileDevice::FileBirthTime);
destFile.setFileTime(origFile.fileTime(QFileDevice::FileModificationTime), QFileDevice::FileModificationTime);
destFile.close();
}
void CompressionThread::optimizePNG(QString file, int level)
{
QString exec = QString(R"(-o %1 "%2")").arg(QString::number(level), file);
#ifdef Q_OS_WIN
startBlockingProcess("tools\\optipng.exe", exec);
#else
startBlockingProcess("optipng", exec);
#endif
}