Fix saving existing cover from file embedded for multiple albums

This commit is contained in:
Jonas Kvinge
2021-03-07 07:01:22 +01:00
parent 3e6029d33c
commit e2cd68e3e8
3 changed files with 59 additions and 18 deletions

View File

@@ -122,6 +122,25 @@ QByteArray ImageUtils::SaveImageToJpegData(const QImage &image) {
} }
QByteArray ImageUtils::FileToJpegData(const QString &filename) {
if (filename.isEmpty()) return QByteArray();
QByteArray image_data = Utilities::ReadDataFromFile(filename);
if (Utilities::MimeTypeFromData(image_data) == "image/jpeg") return image_data;
else {
QImage image;
if (image.loadFromData(image_data)) {
if (!image.isNull()) {
image_data = SaveImageToJpegData(image);
}
}
}
return image_data;
}
QImage ImageUtils::ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height) { QImage ImageUtils::ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height) {
if (image.isNull()) return image; if (image.isNull()) return image;

View File

@@ -41,6 +41,7 @@ class ImageUtils {
static QStringList SupportedImageFormats(); static QStringList SupportedImageFormats();
static QList<QByteArray> ImageFormatsForMimeType(const QByteArray &mimetype); static QList<QByteArray> ImageFormatsForMimeType(const QByteArray &mimetype);
static QByteArray SaveImageToJpegData(const QImage &image = QImage()); static QByteArray SaveImageToJpegData(const QImage &image = QImage());
static QByteArray FileToJpegData(const QString &filename);
static QPixmap TryLoadPixmap(const QUrl &automatic, const QUrl &manual, const QUrl &url = QUrl()); static QPixmap TryLoadPixmap(const QUrl &automatic, const QUrl &manual, const QUrl &url = QUrl());
static QImage ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height); static QImage ScaleAndPad(const QImage &image, const bool scale, const bool pad, const int desired_height);
static QImage CreateThumbnail(const QImage &image, const bool pad, const QSize size); static QImage CreateThumbnail(const QImage &image, const bool pad, const QSize size);

View File

@@ -834,6 +834,10 @@ void EditTagDialog::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderRes
} }
else { else {
ui_->tags_art->setPixmap(QPixmap::fromImage(image_no_cover_thumbnail_)); ui_->tags_art->setPixmap(QPixmap::fromImage(image_no_cover_thumbnail_));
for (const QModelIndex &idx : ui_->song_list->selectionModel()->selectedIndexes()) {
data_[idx.row()].cover_result_ = AlbumCoverImageResult();
enable_change_art = data_[idx.row()].original_.is_collection_song();
}
} }
tags_cover_art_id_ = -1; tags_cover_art_id_ = -1;
album_cover_choice_controller_->show_cover_action()->setEnabled(result.success && result.type != AlbumCoverLoaderResult::Type_ManuallyUnset); album_cover_choice_controller_->show_cover_action()->setEnabled(result.success && result.type != AlbumCoverLoaderResult::Type_ManuallyUnset);
@@ -1071,20 +1075,17 @@ void EditTagDialog::SaveData() {
QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_); }, Qt::QueuedConnection); QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_); }, Qt::QueuedConnection);
} }
QString embedded_cover_from_file;
// If embedded album cover is selected and it isn't saved to the tags, then save it even if no action was done. // If embedded album cover is selected and it isn't saved to the tags, then save it even if no action was done.
if (ui_->checkbox_embedded_cover->isChecked() && ref.cover_action_ == UpdateCoverAction_None && !ref.original_.has_embedded_cover() && ref.original_.save_embedded_cover_supported() && if (ui_->checkbox_embedded_cover->isChecked() && ref.cover_action_ == UpdateCoverAction_None && !ref.original_.has_embedded_cover() && ref.original_.save_embedded_cover_supported()) {
( if (ref.original_.art_manual().isValid() && ref.original_.art_manual().isLocalFile() && QFile::exists(ref.original_.art_manual().toLocalFile())) {
(ref.original_.art_automatic().isValid() && ref.cover_action_ = UpdateCoverAction_New;
ref.original_.art_automatic().isLocalFile() && embedded_cover_from_file = ref.original_.art_manual().toLocalFile();
QFile::exists(ref.original_.art_automatic().toLocalFile())) }
|| else if (ref.original_.art_automatic().isValid() && ref.original_.art_automatic().isLocalFile() && QFile::exists(ref.original_.art_automatic().toLocalFile())) {
(ref.original_.art_manual().isValid() && ref.cover_action_ = UpdateCoverAction_New;
ref.original_.art_manual().isLocalFile() && embedded_cover_from_file = ref.original_.art_automatic().toLocalFile();
QFile::exists(ref.original_.art_manual().toLocalFile())) }
)) {
ref.cover_action_ = UpdateCoverAction_New;
ref.current_.clear_art_automatic();
ref.current_.clear_art_manual();
} }
if (ref.cover_action_ != UpdateCoverAction_None) { if (ref.cover_action_ != UpdateCoverAction_None) {
@@ -1141,16 +1142,16 @@ void EditTagDialog::SaveData() {
} }
} }
if (ui_->checkbox_embedded_cover->isChecked() && ref.original_.save_embedded_cover_supported()) { if (ui_->checkbox_embedded_cover->isChecked() && ref.original_.save_embedded_cover_supported()) {
if (ref.cover_action_ != UpdateCoverAction_Clear && ref.cover_action_ != UpdateCoverAction_Unset) { if (ref.cover_action_ == UpdateCoverAction_New) { // Save JPEG data directly.
++save_art_pending_; if (ref.cover_result_.is_jpeg()) {
if (ref.cover_action_ == UpdateCoverAction_Delete && ref.cover_result_.is_valid()) ref.cover_result_ = AlbumCoverImageResult(); ++save_art_pending_;
if (ref.cover_result_.is_jpeg() || ref.cover_result_.image_data.isNull()) {
TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), ref.cover_result_.image_data); TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), ref.cover_result_.image_data);
QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() {
SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_); SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
} }
else { else if (!ref.cover_result_.image.isNull()) { // Convert image data to JPEG.
++save_art_pending_;
QFuture<QByteArray> future = QtConcurrent::run(&ImageUtils::SaveImageToJpegData, ref.cover_result_.image); QFuture<QByteArray> future = QtConcurrent::run(&ImageUtils::SaveImageToJpegData, ref.cover_result_.image);
QFutureWatcher<QByteArray> *watcher = new QFutureWatcher<QByteArray>(); QFutureWatcher<QByteArray> *watcher = new QFutureWatcher<QByteArray>();
watcher->setFuture(future); watcher->setFuture(future);
@@ -1162,6 +1163,26 @@ void EditTagDialog::SaveData() {
watcher->deleteLater(); watcher->deleteLater();
}); });
} }
else if (!embedded_cover_from_file.isEmpty()) { // Save existing file on disk as embedded cover.
++save_art_pending_;
QFuture<QByteArray> future = QtConcurrent::run(&ImageUtils::FileToJpegData, embedded_cover_from_file);
QFutureWatcher<QByteArray> *watcher = new QFutureWatcher<QByteArray>();
watcher->setFuture(future);
QObject::connect(watcher, &QFutureWatcher<QByteArray>::finished, this, [=]() {
TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), watcher->result());
QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() {
SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_);
}, Qt::QueuedConnection);
watcher->deleteLater();
});
}
}
else if (ref.cover_action_ == UpdateCoverAction_Delete) {
++save_art_pending_;
TagReaderReply *reply = TagReaderClient::Instance()->SaveEmbeddedArt(ref.current_.url().toLocalFile(), QByteArray());
QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() {
SongSaveArtComplete(reply, ref.current_.url().toLocalFile(), ref.current_, ref.cover_action_);
}, Qt::QueuedConnection);
} }
} }
else if (!ref.current_.effective_albumartist().isEmpty() && !ref.current_.album().isEmpty()) { else if (!ref.current_.effective_albumartist().isEmpty() && !ref.current_.album().isEmpty()) {