Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 44 additions & 14 deletions libimageviewer/service/aimodelservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,13 +480,26 @@ bool AIModelService::isWaitSave() const
return dptr->waitSave;
}

/**
@return 返回当前增强图片(若为)是否需要保存,已保存和非增强图片返回 false .
*/
bool AIModelService::imageNeedSave(const QString &filePath) const
{
auto ptr = dptr->enhanceCache.value(filePath);
if (!ptr.isNull()) {
return !ptr->saved;
}

return false;
}

/**
@brief 弹出对话框提示是否保存当前文件 \a filePath
*/
void AIModelService::saveFileDialog(const QString &filePath, QWidget *target)
bool AIModelService::saveFileDialog(const QString &filePath, QWidget *target)
{
if (isWaitSave()) {
return;
return false;
}
dptr->waitSave = true;

Expand All @@ -504,37 +517,39 @@ void AIModelService::saveFileDialog(const QString &filePath, QWidget *target)
}
});

bool saveSucc = false;
int ret = expiredDialog.exec();
if (ret == suggestRet) {
saveEnhanceFileAs(filePath, target);
saveSucc = saveEnhanceFileAs(filePath, target);
}

dptr->waitSave = false;
return saveSucc;
}

/**
@brief 保存增强后的图像 \a filePath , 如果非图像增强文件则不进行保存
*/
void AIModelService::saveEnhanceFile(const QString &filePath)
bool AIModelService::saveEnhanceFile(const QString &filePath)
{
if (!isTemporaryFile(filePath)) {
return;
return false;
}

// 覆盖原文件
saveFile(filePath, sourceFilePath(filePath));
return saveFile(filePath, sourceFilePath(filePath));
}

/**
@brief 另存增强后的图像 \a filePath , 如果非图像增强文件则不进行保存
*/
void AIModelService::saveEnhanceFileAs(const QString &filePath, QWidget *target)
bool AIModelService::saveEnhanceFileAs(const QString &filePath, QWidget *target)
{
if (!isTemporaryFile(filePath)) {
return;
return false;
}

saveTemporaryAs(filePath, sourceFilePath(filePath), target);
return saveTemporaryAs(filePath, sourceFilePath(filePath), target);
}

/**
Expand Down Expand Up @@ -640,6 +655,7 @@ void AIModelService::showWarningDialog(const QString &notify, QWidget *target)
/**
@brief 保存文件 \a filePath 到 \a newPath , 默认覆盖 \a newPath 存在文件时无效,
需要先移除旧文件。
通过此处保存的图像增强文件会被设置为已保存状态。
*/
bool AIModelService::saveFile(const QString &filePath, const QString &newPath)
{
Expand All @@ -655,6 +671,11 @@ bool AIModelService::saveFile(const QString &filePath, const QString &newPath)
bool ret = QFile::copy(filePath, newPath);
if (!ret) {
qWarning() << QString("Copy temporary file %1 failed").arg(filePath);
} else {
auto ptr = dptr->enhanceCache.value(filePath);
if (!ptr.isNull()) {
ptr->saved = true;
}
}

return ret;
Expand All @@ -663,8 +684,9 @@ bool AIModelService::saveFile(const QString &filePath, const QString &newPath)
/**
@brief 弹出保存框将 \a filePath 保存,建议目录为源文件目录 \a sourcePath
*/
void AIModelService::saveTemporaryAs(const QString &filePath, const QString &sourcePath, QWidget *target)
bool AIModelService::saveTemporaryAs(const QString &filePath, const QString &sourcePath, QWidget *target)
{
bool saveSucc = false;
// 保存文件路径异常会尝试重试
bool retry = false;
do {
Expand All @@ -687,7 +709,7 @@ void AIModelService::saveTemporaryAs(const QString &filePath, const QString &sou
if (QDialog::Accepted == mode) {
auto files = dialog.selectedFiles();
if (files.isEmpty()) {
return;
return false;
}

QString newPath = files.value(0);
Expand All @@ -698,9 +720,11 @@ void AIModelService::saveTemporaryAs(const QString &filePath, const QString &sou
continue;
}

saveFile(filePath, newPath);
saveSucc = saveFile(filePath, newPath);
}
} while (retry);

return saveSucc;
}

/**
Expand All @@ -710,9 +734,15 @@ void AIModelService::saveTemporaryAs(const QString &filePath, const QString &sou
QString AIModelService::checkConvertFile(const QString &filePath, const QImage &image) const
{
// 判断图片变更
QFileInfo info(filePath);
QMutexLocker _locker(&dptr->cacheMutex);
if (dptr->convertCache.contains(filePath)) {
return dptr->convertCache.value(filePath);
auto &sourceCache = dptr->convertCache[filePath];

// 判断文件是否变更(根据修改时间)
if (info.lastModified() == sourceCache.lastModified) {
return dptr->convertCache.value(filePath).cachedImage;
}
}

if (image.isNull()) {
Expand All @@ -728,7 +758,7 @@ QString AIModelService::checkConvertFile(const QString &filePath, const QImage &
}

_locker.relock();
dptr->convertCache.insert(filePath, cvtFile);
dptr->convertCache.insert(filePath, {info.lastModified(), cvtFile});
return cvtFile;
}

Expand Down
9 changes: 5 additions & 4 deletions libimageviewer/service/aimodelservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ class AIModelService : public QObject
QString lastProcOutput() const;

bool isWaitSave() const;
void saveFileDialog(const QString &filePath, QWidget *target = nullptr);
void saveEnhanceFile(const QString &filePath);
void saveEnhanceFileAs(const QString &filePath, QWidget *target = nullptr);
bool imageNeedSave(const QString &filePath) const;
bool saveFileDialog(const QString &filePath, QWidget *target = nullptr);
bool saveEnhanceFile(const QString &filePath);
bool saveEnhanceFileAs(const QString &filePath, QWidget *target = nullptr);

bool detectErrorAndNotify(QWidget *targetWidget, Error error, const QString &output = QString::null);

Expand All @@ -60,7 +61,7 @@ class AIModelService : public QObject
bool checkFileSavable(const QString &newPath, QWidget *target = nullptr);
void showWarningDialog(const QString &notify, QWidget *target = nullptr);
bool saveFile(const QString &filePath, const QString &newPath);
void saveTemporaryAs(const QString &filePath, const QString &sourcePath, QWidget *target = nullptr);
bool saveTemporaryAs(const QString &filePath, const QString &sourcePath, QWidget *target = nullptr);
QString checkConvertFile(const QString &filePath, const QImage &image) const;

// DBus
Expand Down
12 changes: 10 additions & 2 deletions libimageviewer/service/aimodelservice_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <QTemporaryDir>
#include <QDBusInterface>
#include <QBasicTimer>
#include <QDateTime>

#include <DFloatingMessage>

Expand All @@ -37,7 +38,9 @@ struct EnhanceInfo
const QString output;
const QString model;
int index = 0;
bool saved = false; // 当前增强图片是否已保存

// 线程争用
QAtomicInt state = AIModelService::None; // 处理状态,可能有争用

EnhanceInfo(const QString &s, const QString &o, const QString &m)
Expand Down Expand Up @@ -93,8 +96,13 @@ class AIModelServiceData
QHash<QString, EnhancePtr> enhanceCache; // 图像增强缓存信息(仅主线程访问)

QMutex cacheMutex;
QTemporaryDir convertTemp; // 图像类型转换文件临时目录
QHash<QString, QString> convertCache; // 缓存的信息,可能多个线程访问
QTemporaryDir convertTemp; // 图像类型转换文件临时目录
struct SourceCache
{
QDateTime lastModified; // 文件最后修改时间
QString cachedImage; // 文件缓存路径
};
QHash<QString, SourceCache> convertCache; // 缓存的信息,可能多个线程访问

QFutureWatcher<EnhancePtr> enhanceWatcher;

Expand Down
11 changes: 5 additions & 6 deletions libimageviewer/viewpanel/viewpanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1669,8 +1669,8 @@ void LibViewPanel::onMenuItemClicked(QAction *action)
m_bottomToolbar->setVisible(false);
}

// 判断当前是否为AI增强图片,若为则设置为提示是否保存
if (AIModelService::instance()->isTemporaryFile(m_currentPath)
// 判断当前AI增强图片是否需要保存,若为则提示是否保存
if (AIModelService::instance()->imageNeedSave(m_currentPath)
&& !AIModelService::instance()->isWaitSave()) {
AIModelService::instance()->saveFileDialog(m_currentPath, this);
resetAIEnhanceImage();
Expand Down Expand Up @@ -1987,8 +1987,8 @@ void LibViewPanel::resetBottomToolbarGeometry(bool visible)
void LibViewPanel::openImg(int index, QString path)
{
if (AIModelService::instance()->isValid()) {
// 判断当前图片是否为图像增强图片
bool previousEnhanced = AIModelService::instance()->isTemporaryFile(m_currentPath);
// 判断当前AI增强图片是否需要保存
bool previousEnhanced = AIModelService::instance()->imageNeedSave(m_currentPath);
if (previousEnhanced) {
if (AIModelService::instance()->isWaitSave()) {
return;
Expand Down Expand Up @@ -2265,11 +2265,10 @@ void LibViewPanel::createAIBtn()
connect(m_AIFloatBar, &AIEnhanceFloatWidget::reset, this, &LibViewPanel::resetAIEnhanceImage);
connect(m_AIFloatBar, &AIEnhanceFloatWidget::save, this, [this](){
AIModelService::instance()->saveEnhanceFile(m_currentPath);
resetAIEnhanceImage();
});
connect(m_AIFloatBar, &AIEnhanceFloatWidget::saveAs, this, [this](){
AIModelService::instance()->saveEnhanceFileAs(m_currentPath, this);
resetAIEnhanceImage();
// 保存文件后不再主动退出当前图片
});
}
}
Expand Down