Generate good thumbnail for animated stickers.

This commit is contained in:
John Preston 2019-07-04 10:20:36 +02:00
parent 7034df49e9
commit 0a63eac4f6
4 changed files with 43 additions and 7 deletions

View File

@ -636,7 +636,10 @@ Image *DocumentData::goodThumbnail() const {
} }
void DocumentData::validateGoodThumbnail() { void DocumentData::validateGoodThumbnail() {
if (!isVideoFile() && !isAnimation() && !isWallPaper()) { if (!isVideoFile()
&& !isAnimation()
&& !isWallPaper()
&& (!sticker() || !sticker()->animated)) {
_goodThumbnail = nullptr; _goodThumbnail = nullptr;
} else if (!_goodThumbnail && hasRemoteLocation()) { } else if (!_goodThumbnail && hasRemoteLocation()) {
_goodThumbnail = std::make_unique<Image>( _goodThumbnail = std::make_unique<Image>(
@ -665,7 +668,10 @@ void DocumentData::setGoodThumbnailOnUpload(
} }
_goodThumbnail = std::make_unique<Image>( _goodThumbnail = std::make_unique<Image>(
std::make_unique<Images::LocalFileSource>( std::make_unique<Images::LocalFileSource>(
QString(), std::move(bytes), "JPG", std::move(image))); QString(),
std::move(bytes),
sticker() ? "WEBP" : "JPG",
std::move(image)));
} }
auto DocumentData::bigFileBaseCacheKey() const auto DocumentData::bigFileBaseCacheKey() const

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h" #include "data/data_document.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "media/clip/media_clip_reader.h" #include "media/clip/media_clip_reader.h"
#include "lottie/lottie_animation.h"
#include "auth_session.h" #include "auth_session.h"
namespace Data { namespace Data {
@ -19,12 +20,20 @@ namespace {
constexpr auto kGoodThumbQuality = 87; constexpr auto kGoodThumbQuality = 87;
constexpr auto kWallPaperSize = 960; constexpr auto kWallPaperSize = 960;
enum class FileType {
Video,
AnimatedSticker,
WallPaper,
};
QImage Prepare( QImage Prepare(
const QString &path, const QString &path,
QByteArray data, QByteArray data,
bool isWallPaper) { FileType type) {
if (!isWallPaper) { if (type == FileType::Video) {
return Media::Clip::PrepareForSending(path, data).thumbnail; return Media::Clip::PrepareForSending(path, data).thumbnail;
} else if (type == FileType::AnimatedSticker) {
return Lottie::ReadThumbnail(Lottie::ReadContent(data, path));
} }
const auto validateSize = [](QSize size) { const auto validateSize = [](QSize size) {
return (size.width() + size.height()) < 10'000; return (size.width() + size.height()) < 10'000;
@ -64,7 +73,11 @@ void GoodThumbSource::generate(base::binary_guard &&guard) {
return; return;
} }
const auto data = _document->data(); const auto data = _document->data();
const auto isWallPaper = _document->isWallPaper(); const auto type = _document->isWallPaper()
? FileType::WallPaper
: _document->sticker()
? FileType::AnimatedSticker
: FileType::Video;
auto location = _document->location().isEmpty() auto location = _document->location().isEmpty()
? nullptr ? nullptr
: std::make_unique<FileLocation>(_document->location()); : std::make_unique<FileLocation>(_document->location());
@ -80,11 +93,13 @@ void GoodThumbSource::generate(base::binary_guard &&guard) {
const auto filepath = (location && location->accessEnable()) const auto filepath = (location && location->accessEnable())
? location->name() ? location->name()
: QString(); : QString();
auto result = Prepare(filepath, data, isWallPaper); auto result = Prepare(filepath, data, type);
auto bytes = QByteArray(); auto bytes = QByteArray();
if (!result.isNull()) { if (!result.isNull()) {
auto buffer = QBuffer(&bytes); auto buffer = QBuffer(&bytes);
const auto format = (isWallPaper && result.hasAlphaChannel()) const auto format = (type == FileType::AnimatedSticker)
? "WEBP"
: (type == FileType::WallPaper && result.hasAlphaChannel())
? "PNG" ? "PNG"
: "JPG"; : "JPG";
result.save(&buffer, format, kGoodThumbQuality); result.save(&buffer, format, kGoodThumbQuality);

View File

@ -156,6 +156,10 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, c
const auto w = _pixw; const auto w = _pixw;
const auto h = _pixh; const auto h = _pixh;
const auto &c = st::msgStickerOverlay; const auto &c = st::msgStickerOverlay;
const auto good = _data->goodThumbnail();
if (!lottieReady && good && !good->loaded()) {
good->load({});
}
static QPixmap empty; static QPixmap empty;
if (lottieReady) { if (lottieReady) {
return empty; return empty;
@ -170,6 +174,10 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, c
// return selected // return selected
// ? blurred->pixBlurredColored(o, c, w, h) // ? blurred->pixBlurredColored(o, c, w, h)
// : blurred->pixBlurred(o, w, h); // : blurred->pixBlurred(o, w, h);
} else if (good && good->loaded()) {
return selected
? good->pixColored(o, c, w, h)
: good->pix(o, w, h);
} else if (const auto thumbnail = _data->thumbnail()) { } else if (const auto thumbnail = _data->thumbnail()) {
return selected return selected
? thumbnail->pixBlurredColored(o, c, w, h) ? thumbnail->pixBlurredColored(o, c, w, h)

View File

@ -894,6 +894,13 @@ void FileLoadTask::process() {
MTP_string(QString()), MTP_string(QString()),
MTP_inputStickerSetEmpty(), MTP_inputStickerSetEmpty(),
MTPMaskCoords())); MTPMaskCoords()));
if (isAnimation) {
goodThumbnail = fullimage;
{
QBuffer buffer(&goodThumbnailBytes);
goodThumbnail.save(&buffer, "WEBP", kThumbnailQuality);
}
}
} else if (isAnimation) { } else if (isAnimation) {
attributes.push_back(MTP_documentAttributeAnimated()); attributes.push_back(MTP_documentAttributeAnimated());
} else if (_type != SendMediaType::File) { } else if (_type != SendMediaType::File) {