Generate high quality thumbnail on sending video.

This commit is contained in:
John Preston 2018-10-25 12:47:06 +04:00
parent da358615e0
commit 8000ff2cd7
6 changed files with 60 additions and 13 deletions

View File

@ -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<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 {
return (type == StickerDocument && size < Storage::kMaxStickerInMemory)
|| (isAnimation() && size < Storage::kMaxAnimationInMemory)

View File

@ -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;

View File

@ -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;
}

View File

@ -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<Data::UploadState>(document->size);
document->setGoodThumbnail(
std::move(file->goodThumbnail),
std::move(file->goodThumbnailBytes));
if (!file->content.isEmpty()) {
document->setData(file->content);
if (document->saveToCache()

View File

@ -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<MTPPhotoSize> photoSizes;
QImage thumb;
QImage thumb, goodThumbnail;
QByteArray goodThumbnailBytes;
QVector<MTPDocumentAttribute> 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<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));
}
}
@ -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;

View File

@ -216,6 +216,9 @@ struct FileLoadResult {
QByteArray thumbmd5;
QImage thumb;
QImage goodThumbnail;
QByteArray goodThumbnailBytes;
MTPPhoto photo;
MTPDocument document;