mirror of https://github.com/procxx/kepka.git
				
				
				
			Generate high quality thumbnail on sending video.
This commit is contained in:
		
							parent
							
								
									da358615e0
								
							
						
					
					
						commit
						8000ff2cd7
					
				| 
						 | 
					@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "window/window_controller.h"
 | 
					#include "window/window_controller.h"
 | 
				
			||||||
#include "storage/cache/storage_cache_database.h"
 | 
					#include "storage/cache/storage_cache_database.h"
 | 
				
			||||||
#include "ui/image/image.h"
 | 
					#include "ui/image/image.h"
 | 
				
			||||||
 | 
					#include "ui/image/image_source.h"
 | 
				
			||||||
#include "auth_session.h"
 | 
					#include "auth_session.h"
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
#include "messenger.h"
 | 
					#include "messenger.h"
 | 
				
			||||||
| 
						 | 
					@ -550,12 +551,23 @@ void DocumentData::validateGoodThumbnail() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DocumentData::refreshGoodThumbnail() {
 | 
					void DocumentData::refreshGoodThumbnail() {
 | 
				
			||||||
	if (_goodThumbnail && !_goodThumbnail->loaded()) {
 | 
						if (_goodThumbnail && hasRemoteLocation()) {
 | 
				
			||||||
		_goodThumbnail->replaceSource(
 | 
							_goodThumbnail->replaceSource(
 | 
				
			||||||
			std::make_unique<Data::GoodThumbSource>(this));
 | 
								std::make_unique<Data::GoodThumbSource>(this));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void DocumentData::setGoodThumbnail(QImage &&image, QByteArray &&bytes) {
 | 
				
			||||||
 | 
						Expects(uploadingData != nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (image.isNull()) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_goodThumbnail = std::make_unique<Image>(
 | 
				
			||||||
 | 
							std::make_unique<Images::LocalFileSource>(
 | 
				
			||||||
 | 
								QString(), std::move(bytes), "JPG", std::move(image)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool DocumentData::saveToCache() const {
 | 
					bool DocumentData::saveToCache() const {
 | 
				
			||||||
	return (type == StickerDocument && size < Storage::kMaxStickerInMemory)
 | 
						return (type == StickerDocument && size < Storage::kMaxStickerInMemory)
 | 
				
			||||||
		|| (isAnimation() && size < Storage::kMaxAnimationInMemory)
 | 
							|| (isAnimation() && size < Storage::kMaxAnimationInMemory)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,7 +156,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Image *goodThumbnail() const;
 | 
						Image *goodThumbnail() const;
 | 
				
			||||||
	Storage::Cache::Key goodThumbnailCacheKey() const;
 | 
						Storage::Cache::Key goodThumbnailCacheKey() const;
 | 
				
			||||||
	void validateGoodThumbnail();
 | 
						void setGoodThumbnail(QImage &&image, QByteArray &&bytes);
 | 
				
			||||||
	void refreshGoodThumbnail();
 | 
						void refreshGoodThumbnail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setRemoteLocation(
 | 
						void setRemoteLocation(
 | 
				
			||||||
| 
						 | 
					@ -211,6 +211,7 @@ private:
 | 
				
			||||||
	friend class Serialize::Document;
 | 
						friend class Serialize::Document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LocationType locationType() const;
 | 
						LocationType locationType() const;
 | 
				
			||||||
 | 
						void validateGoodThumbnail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const;
 | 
						void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -676,6 +676,23 @@ bool MediaFile::updateSentMedia(const MTPMessageMedia &media) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	Auth().data().documentConvert(_document, data.vdocument);
 | 
						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;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,8 +157,11 @@ void Uploader::upload(
 | 
				
			||||||
			? Auth().data().document(file->document)
 | 
								? Auth().data().document(file->document)
 | 
				
			||||||
			: Auth().data().document(
 | 
								: Auth().data().document(
 | 
				
			||||||
				file->document,
 | 
									file->document,
 | 
				
			||||||
				base::duplicate(file->thumb));
 | 
									std::move(file->thumb));
 | 
				
			||||||
		document->uploadingData = std::make_unique<Data::UploadState>(document->size);
 | 
							document->uploadingData = std::make_unique<Data::UploadState>(document->size);
 | 
				
			||||||
 | 
							document->setGoodThumbnail(
 | 
				
			||||||
 | 
								std::move(file->goodThumbnail),
 | 
				
			||||||
 | 
								std::move(file->goodThumbnailBytes));
 | 
				
			||||||
		if (!file->content.isEmpty()) {
 | 
							if (!file->content.isEmpty()) {
 | 
				
			||||||
			document->setData(file->content);
 | 
								document->setData(file->content);
 | 
				
			||||||
			if (document->saveToCache()
 | 
								if (document->saveToCache()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "storage/file_download.h"
 | 
					#include "storage/file_download.h"
 | 
				
			||||||
#include "storage/storage_media_prepare.h"
 | 
					#include "storage/storage_media_prepare.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr auto kThumbnailQuality = 87;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Storage::ValidateThumbDimensions;
 | 
					using Storage::ValidateThumbDimensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SendMediaReady PreparePeerPhoto(PeerId peerId, QImage &&image) {
 | 
					SendMediaReady PreparePeerPhoto(PeerId peerId, QImage &&image) {
 | 
				
			||||||
| 
						 | 
					@ -531,7 +537,8 @@ void FileLoadTask::process() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PreparedPhotoThumbs photoThumbs;
 | 
						PreparedPhotoThumbs photoThumbs;
 | 
				
			||||||
	QVector<MTPPhotoSize> photoSizes;
 | 
						QVector<MTPPhotoSize> photoSizes;
 | 
				
			||||||
	QImage thumb;
 | 
						QImage thumb, goodThumbnail;
 | 
				
			||||||
 | 
						QByteArray goodThumbnailBytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QVector<MTPDocumentAttribute> attributes(1, MTP_documentAttributeFilename(MTP_string(filename)));
 | 
						QVector<MTPDocumentAttribute> attributes(1, MTP_documentAttributeFilename(MTP_string(filename)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -577,19 +584,20 @@ void FileLoadTask::process() {
 | 
				
			||||||
			auto flags = MTPDdocumentAttributeVideo::Flags(0);
 | 
								auto flags = MTPDdocumentAttributeVideo::Flags(0);
 | 
				
			||||||
			attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(video->duration), MTP_int(coverWidth), MTP_int(coverHeight)));
 | 
								attributes.push_back(MTP_documentAttributeVideo(MTP_flags(flags), MTP_int(video->duration), MTP_int(coverWidth), MTP_int(coverHeight)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto cover = (coverWidth > 90 || coverHeight > 90)
 | 
								goodThumbnail = video->thumbnail;
 | 
				
			||||||
				? video->thumbnail.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation)
 | 
					 | 
				
			||||||
				: std::move(video->thumbnail);
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				auto thumbFormat = QByteArray("JPG");
 | 
									QBuffer buffer(&goodThumbnailBytes);
 | 
				
			||||||
				auto thumbQuality = 87;
 | 
									goodThumbnail.save(&buffer, "JPG", kThumbnailQuality);
 | 
				
			||||||
 | 
					 | 
				
			||||||
				QBuffer buffer(&thumbdata);
 | 
					 | 
				
			||||||
				cover.save(&buffer, thumbFormat, thumbQuality);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			thumbId = rand_value<uint64>();
 | 
								thumbId = rand_value<uint64>();
 | 
				
			||||||
			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));
 | 
								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->setThumbData(thumbdata);
 | 
				
			||||||
	_result->thumb = std::move(thumb);
 | 
						_result->thumb = std::move(thumb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_result->goodThumbnail = std::move(goodThumbnail);
 | 
				
			||||||
 | 
						_result->goodThumbnailBytes = std::move(goodThumbnailBytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_result->photo = photo;
 | 
						_result->photo = photo;
 | 
				
			||||||
	_result->document = document;
 | 
						_result->document = document;
 | 
				
			||||||
	_result->photoThumbs = photoThumbs;
 | 
						_result->photoThumbs = photoThumbs;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,6 +216,9 @@ struct FileLoadResult {
 | 
				
			||||||
	QByteArray thumbmd5;
 | 
						QByteArray thumbmd5;
 | 
				
			||||||
	QImage thumb;
 | 
						QImage thumb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QImage goodThumbnail;
 | 
				
			||||||
 | 
						QByteArray goodThumbnailBytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MTPPhoto photo;
 | 
						MTPPhoto photo;
 | 
				
			||||||
	MTPDocument document;
 | 
						MTPDocument document;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue