Au lieu de mille mots ...xZibit est également content, car ici les GIF sont insérés dans des autocollants pour être insérés dans des GIF pour KDPV!Et maintenant sur les détails de mise en œuvre.
Tout a commencé par une discussion dans le chat du développeur Telegram sur la fonctionnalité à venir:
![Bohdan Horbeshko, [04/04/19 20:21] Hmm, mais le bot n'acceptera probablement que des gifs, puis convertira ... | Vitaly, [07/04/19 20:22] du gif à Jason? J'aurais regardé :))) | Bohdan Horbeshko, [04.07.19 20:22] Et pourquoi pas? Il existe un éditeur de modèles PlayCanvas dans JSON. | Vitaly, [04/04/19 8:23 pm] et comment est le gif? exporter pixel par pixel? :) | Bohdan Horbeshko, [04/04/19 20:24] Bien sûr, le monde informatique a vu et ne tolérera pas de telles distorsions.](https://habrastorage.org/webt/zu/s5/x1/zus5x1ydd89sejezp98ztbnygto.png)
Un homme a dit - un homme l'a fait! Le premier prototype dans Pillow et svgwrite, analysant les GIF en pixels et les convertissant en carrés vectoriels avec des aperçus en SVG, a été écrit en un jour de congé.
Le plaisir a commencé plus loin ...
JSON est un format ouvert, ils ont dit ...
Jusqu'à présent, avec les formats de Telegram, ils ne cessaient de tromper. Prise en charge des animations GIF - en fait, elles sont converties en vidéo MP4. Prise en charge des autocollants - ils sont téléchargés en PNG, mais convertis en WebP. Cette fois, tout est plus honnête: celui à l'entrée, puis à la sortie.
Pour les autocollants animés, Telegram n'utilise pas de GIF, de vidéos ou même un format graphique vectoriel bien établi tel que SVG, ou, Dieu nous en préserve Cthulhu! - Flash. Il utilise un nouveau format issu de l'aile d'Airbnb - Lottie. Jusqu'à présent, il avait une certaine renommée parmi les développeurs mobiles, mais grâce à Telegram, il pourrait gagner en popularité.
Essentiellement, les fichiers Lottie sont des projets Adobe After Effects sérialisés en JSON qui maximisent toutes les fonctionnalités de ce programme. Avec l'écran, hélas,
tout n'est pas si rose . Bien qu'il existe de nombreuses implémentations «officielles» de la bibliothèque pour le rendu de Lottie, uniquement pour les plates-formes couvertes par Telegram: Android, iOS, Qt et Web - seule une partie des capacités du format est implémentée dans chacune d'elles. Telegram est allé encore plus loin et a
limité la liste des fonctionnalités prises en charge, ainsi que "est venu" avec son propre format, qui diffère de l'habituel Lottie juste en emballant dans GZip et le paramètre
"tgs": 1
. Je pense que je sais où Denis Popov travaille maintenant! :-)
Et si tout va bien avec la documentation des bibliothèques pour différentes plates-formes, alors, hélas, il n'a pas été possible de trouver au moins une description du périphérique de formatage - uniquement le
schéma JSON dans les sources de lottie-web. J'ai dû bricoler en cours de route dans des animations existantes afin de comprendre les concepts généraux du format. Il y avait également des écarts entre les fichiers réels et le schéma: en particulier, dans les
couches de type 4 , selon le schéma, les objets imbriqués sont stockés dans la propriété
"it"
- cependant, dans les fichiers réels, la clé est appelée
"shapes"
et
"it"
ne fonctionne pas.
Les nuances clarifiées du format:
- Un fichier est composé de couches. Contrairement au GIF, chaque couche peut avoir une heure de début et de fin arbitraire pour l'affichage. Différentes transformations peuvent être appliquées au calque (plus précisément, c'est nécessaire ): mise à l'échelle, rotation, changement de transparence, etc. Les couches peuvent même être tridimensionnelles (interdites pour Telegram).
- Un calque est constitué de «formes». Ils ont de nombreux types, certains ne peuvent pas être utilisés dans Telegram. En pratique, pour qu'un calque apparaisse, il doit comprendre trois formes: un chemin (dans les animations terminées, il s'agit généralement du type
"sh"
- courbes de Bézier; le convertisseur utilise jusqu'à présent uniquement le type "rc"
- rectangles), le remplissage (le type "fl"
) et la transformation ( tapez "tr"
). - Vous pouvez même inclure des éléments raster, créer des calques de texte et établir des relations entre les paramètres de calque et de forme via des expressions. Tous ces goodies sont également interdits sur Telegram.
Le premier problème découle directement d'ici: la
redondance . Bien que des valeurs par défaut pour les paramètres de transformation aient récemment été ajoutées au schéma JSON, elles ne sont pas implémentées dans les bibliothèques. Il est donc toujours nécessaire de leur demander explicitement.
Il semblerait que ce ne soit pas du tout un problème? Même un simple GZip fait un bon travail de compression des données qui se répètent de manière flagrante, et 1 Mo de JSON brut se transforme comme par magie en quelques dizaines de kilo-octets, qui se glissent tranquillement dans la limite déclarée de 64 Ko. Ça y était!
Je charge, ce qui signifie une animation joufflue qui affiche calmement lottie-web dans Telegram - et ici au lieu d'un pixel art conditionnellement beau, le regard flou statique qui me regarde est le suivant:

Qu'est-ce que c'est?! Mais il s'est avéré qu'il y a clairement une
limite non spécifiée
de 1 Mo sur les données décompressées. Un représentant de l'équipe Telegram l'a rapidement
confirmé et a annoncé la prochaine augmentation de la limite à 2 Mo.
Même s'ils résolvent ces problèmes, les autocollants qui dépassent 1 Mo de données non compressées et ne contiennent pas de transformations seront inaccessibles aux utilisateurs des anciennes versions de Telegram. Il devra donc probablement se conformer aux restrictions à l'avenir.
La transparence est importante.
Pillow, avec OpenCV, peut être appelé la norme industrielle pour le traitement d'image en Python. De plus, il est également bien affiné pour les fonctionnalités GIF: il prend en charge les couleurs indexées et donne accès à la palette. Il prend en charge la conversion d'une carte de pixels en un tableau NumPy, ce qui est important pour un traitement productif. Recueille même des statistiques sur les couleurs! Mais il y avait aussi des inconvénients:
- Il n'y avait aucun moyen documenté d'obtenir l'indice de couleur transparent. J'ai dû supposer comme solution temporaire que la couleur transparente est la plus courante, mais dans les vrais GIF, ce n'est pas toujours le cas.
- La même chose avec un délai entre les images: Pillow ne donne que les images elles-mêmes comme une séquence d'images, sans information sur les délais.
- Parfois, des trames partielles sont incorrectement superposées.
J'ai donc dû chercher un remplaçant. Le module
gif2numpy a agi comme tel. Il est «affiné» pour les fonctionnalités GIF et donne accès à toutes les propriétés techniques de l'image et des cadres individuels, y compris
GCE . Ainsi, il résout le problème des retards de lecture.
La transparence, comme il s'est avéré, gif2numpy ne la prend pas en charge du tout: les couleurs sont immédiatement converties en trois canaux avec une profondeur de bits en octets, sans prendre en compte la profondeur de bits et enregistrer les indices de couleur. Heureusement, le module se compose d'un fichier, il n'a donc pas été difficile de l'inclure dans le projet et de le modifier en réservant la couleur
#FE00FE
pour la transparence.
Le problème de trame partielle n'était pas trivial à résoudre. gif2numpy
essaie de superposer de telles images sur la précédente, mais il ne vérifie pas les paramètres de superposition, c'est pourquoi le résultat correct ne sort pas toujours. Afin de ne pas
gifsicle
avec les drapeaux, un traitement d'image préliminaire à l'aide de
gifsicle
avec la clé
--unoptimize
est
--unoptimize
- il convertit les images partielles en images complètes. Et en même temps, cela les conduit à utiliser la palette globale, ce qui a éliminé la nécessité de traiter séparément la couleur transparente lors de l'utilisation de votre propre palette de cadres.
Serre-moi plus fort
Les carrés sont bons, mais avec de telles limitations, vous devez faire preuve de plus d'imagination, sinon même les GIF miniatures ne «glisseront» pas dans Telegram.
Quelque chose de similaire à
RLE a été utilisé en premier : les carrés adjacents horizontalement de la même couleur sont combinés en un seul rectangle.
Ensuite, l'exploitation des fonctionnalités de Lottie. Étant donné que chaque couche a une heure de début et de fin arbitraire, vous pouvez appliquer une technique qui a longtemps été utilisée par les codecs vidéo, et en partie dans GIF lui-même: les carrés qui restent au même endroit pour plusieurs images peuvent être fusionnés en une seule couche, pendant laquelle l'affichage change plusieurs autres. Ce qui n'est mis en œuvre jusqu'à présent que pour des paires de couches adjacentes.
Plans de développement
Les idées qui peuvent être appliquées ici sont en vrac:
Les références
- Sources . Effrayant par endroits.
- Chaîne sur laquelle je télécharge des packs de GIF convertis avec succès.