From 8000ff2cd7223f337d188e139a380e7f7171c13f Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 25 Oct 2018 12:47:06 +0400 Subject: [PATCH] Generate high quality thumbnail on sending video. --- Telegram/SourceFiles/data/data_document.cpp | 14 ++++++++- Telegram/SourceFiles/data/data_document.h | 3 +- .../SourceFiles/data/data_media_types.cpp | 17 ++++++++++ Telegram/SourceFiles/storage/file_upload.cpp | 5 ++- .../SourceFiles/storage/localimageloader.cpp | 31 +++++++++++++------ .../SourceFiles/storage/localimageloader.h | 3 ++ 6 files changed, 60 insertions(+), 13 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index d5931c7db..2716b0fe3 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "storage/cache/storage_cache_database.h" #include "ui/image/image.h" +#include "ui/image/image_source.h" #include "auth_session.h" #include "mainwindow.h" #include "messenger.h" @@ -550,12 +551,23 @@ void DocumentData::validateGoodThumbnail() { } void DocumentData::refreshGoodThumbnail() { - if (_goodThumbnail && !_goodThumbnail->loaded()) { + if (_goodThumbnail && hasRemoteLocation()) { _goodThumbnail->replaceSource( std::make_unique(this)); } } +void DocumentData::setGoodThumbnail(QImage &&image, QByteArray &&bytes) { + Expects(uploadingData != nullptr); + + if (image.isNull()) { + return; + } + _goodThumbnail = std::make_unique( + std::make_unique( + QString(), std::move(bytes), "JPG", std::move(image))); +} + bool DocumentData::saveToCache() const { return (type == StickerDocument && size < Storage::kMaxStickerInMemory) || (isAnimation() && size < Storage::kMaxAnimationInMemory) diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index ad3370991..35a9edf35 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -156,7 +156,7 @@ public: Image *goodThumbnail() const; Storage::Cache::Key goodThumbnailCacheKey() const; - void validateGoodThumbnail(); + void setGoodThumbnail(QImage &&image, QByteArray &&bytes); void refreshGoodThumbnail(); void setRemoteLocation( @@ -211,6 +211,7 @@ private: friend class Serialize::Document; LocationType locationType() const; + void validateGoodThumbnail(); void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 9ff6b5c1f..c7ffebe1b 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -676,6 +676,23 @@ bool MediaFile::updateSentMedia(const MTPMessageMedia &media) { return false; } Auth().data().documentConvert(_document, data.vdocument); + + if (const auto good = _document->goodThumbnail()) { + auto bytes = good->bytesForCache(); + if (const auto length = bytes.size()) { + if (length > Storage::kMaxFileInMemory) { + LOG(("App Error: Bad thumbnail data for saving to cache.")); + } else { + Auth().data().cache().putIfEmpty( + _document->goodThumbnailCacheKey(), + Storage::Cache::Database::TaggedValue( + std::move(bytes), + Data::kImageCacheTag)); + _document->refreshGoodThumbnail(); + } + } + } + return true; } diff --git a/Telegram/SourceFiles/storage/file_upload.cpp b/Telegram/SourceFiles/storage/file_upload.cpp index 1d6b9b90f..932ff170a 100644 --- a/Telegram/SourceFiles/storage/file_upload.cpp +++ b/Telegram/SourceFiles/storage/file_upload.cpp @@ -157,8 +157,11 @@ void Uploader::upload( ? Auth().data().document(file->document) : Auth().data().document( file->document, - base::duplicate(file->thumb)); + std::move(file->thumb)); document->uploadingData = std::make_unique(document->size); + document->setGoodThumbnail( + std::move(file->goodThumbnail), + std::move(file->goodThumbnailBytes)); if (!file->content.isEmpty()) { document->setData(file->content); if (document->saveToCache() diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index c89c5657f..f4636b83b 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -20,6 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/file_download.h" #include "storage/storage_media_prepare.h" +namespace { + +constexpr auto kThumbnailQuality = 87; + +} // namespace + using Storage::ValidateThumbDimensions; SendMediaReady PreparePeerPhoto(PeerId peerId, QImage &&image) { @@ -531,7 +537,8 @@ void FileLoadTask::process() { PreparedPhotoThumbs photoThumbs; QVector photoSizes; - QImage thumb; + QImage thumb, goodThumbnail; + QByteArray goodThumbnailBytes; QVector attributes(1, MTP_documentAttributeFilename(MTP_string(filename))); @@ -577,19 +584,20 @@ void FileLoadTask::process() { auto flags = MTPDdocumentAttributeVideo::Flags(0); attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(video->duration), MTP_int(coverWidth), MTP_int(coverHeight))); - auto cover = (coverWidth > 90 || coverHeight > 90) - ? video->thumbnail.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation) - : std::move(video->thumbnail); + goodThumbnail = video->thumbnail; { - auto thumbFormat = QByteArray("JPG"); - auto thumbQuality = 87; - - QBuffer buffer(&thumbdata); - cover.save(&buffer, thumbFormat, thumbQuality); + QBuffer buffer(&goodThumbnailBytes); + goodThumbnail.save(&buffer, "JPG", kThumbnailQuality); } thumbId = rand_value(); - thumb = std::move(cover); + thumb = (coverWidth > 90 || coverHeight > 90) + ? video->thumbnail.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation) + : std::move(video->thumbnail); + { + QBuffer buffer(&thumbdata); + thumb.save(&buffer, "JPG", kThumbnailQuality); + } thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)); } } @@ -701,6 +709,9 @@ void FileLoadTask::process() { _result->setThumbData(thumbdata); _result->thumb = std::move(thumb); + _result->goodThumbnail = std::move(goodThumbnail); + _result->goodThumbnailBytes = std::move(goodThumbnailBytes); + _result->photo = photo; _result->document = document; _result->photoThumbs = photoThumbs; diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index 239d7086d..baf334334 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -216,6 +216,9 @@ struct FileLoadResult { QByteArray thumbmd5; QImage thumb; + QImage goodThumbnail; + QByteArray goodThumbnailBytes; + MTPPhoto photo; MTPDocument document;