Anstelle von tausend Worten ...xZibit freut sich auch, denn hier werden GIFs in Aufkleber eingefügt, um sie in GIFs für KDPV einzufügen!Und nun zu den Implementierungsdetails.
Alles begann mit einer Diskussion im Chat des Telegrammentwicklers über die bevorstehende Funktion:
![Bohdan Horbeshko, [04/04/19 20:21] Hmm, aber der Bot wird wahrscheinlich nur Gifs akzeptieren und dann konvertieren ... | Vitaly, [07/04/19 20:22] vom GIF an Jason? Ich hätte geschaut :))) | Bohdan Horbeshko, [04.07.19 20:22] Und warum nicht? In JSON gibt es einen PlayCanvas-Modelleditor. | Vitaly, [04/04/19 8:23 p.m.] und wie ist das GIF? Pixel für Pixel exportieren? :) | Bohdan Horbeshko, [04/04/19 20:24] Natürlich hat die IT-Welt solche Verzerrungen gesehen und wird sie nicht tolerieren.](https://habrastorage.org/webt/zu/s5/x1/zus5x1ydd89sejezp98ztbnygto.png)
Ein Mann sagte - ein Mann tat es! Der erste Prototyp in Pillow und svgwrite, bei dem GIFs in Pixel analysiert und in Vektorquadrate mit Vorschau in SVG konvertiert wurden, wurde an einem freien Tag geschrieben.
Der Spaß begann weiter ...
JSON ist ein offenes Format, sagten sie ...
Bis jetzt haben sie mit den Formaten in Telegram immer wieder ausgetrickst. Unterstützung für GIF-Animationen - tatsächlich werden sie in MP4-Video konvertiert. Unterstützung für Aufkleber - sie werden in PNG hochgeladen, aber in WebP konvertiert. Diesmal ist alles ehrlicher: am Eingang, dann am Ausgang.
Für animierte Aufkleber verwendet Telegram keine GIFs, Videos oder sogar ein etabliertes Vektorgrafikformat wie SVG oder, Gott bewahre Cthulhu! - Blitz. Es verwendet ein neues Format, das unter dem Flügel von Airbnb - Lottie entstanden ist. Bis jetzt war er unter den Entwicklern von Mobilgeräten bekannt, aber dank Telegram kann es an Popularität gewinnen.
Im Wesentlichen handelt es sich bei Lottie-Dateien um JSON-serialisierte Adobe After Effects-Projekte, die alle Funktionen dieses Programms maximieren. Mit dem Display ist leider
nicht alles so rosig . Obwohl es viele vorgefertigte "offizielle" Implementierungen der Bibliothek zum Rendern von Lottie gibt, nur für die von Telegram abgedeckten Plattformen: Android, iOS, Qt und Web - nur ein Teil der Funktionen des Formats ist in allen implementiert. Telegram ging noch weiter und
beschränkte die Liste der unterstützten Funktionen sowie ein eigenes Format, das sich vom üblichen Lottie nur durch das Einpacken von GZip und den Parameter
"tgs": 1
. Ich glaube ich weiß wo Denis Popov jetzt arbeitet! :-)
Und wenn mit der Dokumentation für Bibliotheken für verschiedene Plattformen alles in Ordnung ist, war es leider nicht möglich, zumindest eine Beschreibung des Formatgeräts zu finden - nur das
JSON-Schema in den Quellen von lottie-web. Ich musste auf dem Weg in vorhandenen Animationen basteln, um die allgemeinen Konzepte des Formats zu verstehen. Es gab auch Diskrepanzen zwischen realen Dateien und dem Schema: Insbesondere in
Schichten vom Typ 4 werden gemäß dem Schema verschachtelte Objekte in der Eigenschaft
"it"
gespeichert. In realen Dateien heißt der Schlüssel jedoch
"shapes"
, und
"it"
funktioniert nicht.
Die geklärten Nuancen des Formats:
- Eine Datei besteht aus Ebenen. Im Gegensatz zu GIF kann hier jede Ebene eine beliebige Start- und Endzeit für die Anzeige haben. Auf die Ebene können verschiedene Transformationen angewendet werden (genauer gesagt, dies ist erforderlich ): Skalieren, Drehen, Ändern der Transparenz usw. Ebenen können sogar dreidimensional sein (für Telegramm verboten).
- Eine Ebene besteht aus „Formen“. Sie haben viele Arten, einige können nicht in Telegramm verwendet werden. In der Praxis sollte eine Ebene drei Formen enthalten: einen Pfad (in fertigen Animationen ist dies normalerweise der Typ
"sh"
- Bezier-Kurven; der Konverter verwendet bisher nur den Typ "rc"
- Rechtecke), die Füllung (der Typ "fl"
) und die Transformation ( Typ "tr"
). - Sie können sogar Rasterelemente einfügen, Textebenen erstellen und durch Ausdrücke Beziehungen zwischen Ebenen- und Formparametern herstellen. All diese Leckereien sind auch im Telegramm verboten.
Das erste Problem folgt direkt von hier:
Redundanz . Obwohl kürzlich Standardwerte für Transformationsparameter zum JSON-Schema hinzugefügt wurden, sind sie nicht in Bibliotheken implementiert. Es ist also immer noch notwendig, sie explizit zu fragen.
Es scheint, dass dies überhaupt kein Problem ist? Sogar ein einfacher GZip komprimiert sich offensichtlich wiederholende Daten gut, und 1 MB roher JSON verwandelt sich auf magische Weise in ein paar zehn Kilobyte, die sich leise in die angegebene Grenze von 64 kB einschleichen. Da war es!
Ich lade, was bedeutet, dass eine mollige Animation, die Lottie-Web in Telegram ruhig anzeigt - und hier anstelle einer bedingt schönen Pixelkunst der statische, verschwommene Blick auf mich lautet:

Was?! Es stellte sich jedoch heraus, dass die dekomprimierten Daten eindeutig
auf 1 MB begrenzt sind. Ein Vertreter des Telegrammteams
bestätigte dies schnell und kündigte die bevorstehende Erhöhung des Limits auf 2 MB an.
Selbst wenn sie diese Probleme lösen, können Benutzer älterer Versionen von Telegram nicht auf Aufkleber zugreifen, die über 1 MB unkomprimierter Daten hinausgehen und keine Transformationen enthalten. Es wird also wahrscheinlich in Zukunft die Einschränkungen einhalten müssen.
Transparenz ist wichtig.
Pillow kann zusammen mit OpenCV als Industriestandard für die Bildverarbeitung in Python bezeichnet werden. Darüber hinaus ist es auch für GIF-Funktionen gut geschärft: Es unterstützt indizierte Farben und ermöglicht den Zugriff auf die Palette. Es unterstützt die Konvertierung einer Pixelkarte in ein NumPy-Array, was für die produktive Verarbeitung wichtig ist. Sammelt sogar Statistiken über Farben! Es gab aber auch Nachteile:
- Es gab keine dokumentierte Möglichkeit, den transparenten Farbindex zu erhalten. Ich musste als vorübergehende Lösung annehmen, dass transparente Farben am häufigsten vorkommen, aber in echten GIFs ist dies nicht immer der Fall.
- Das Gleiche gilt für eine Verzögerung zwischen den Bildern: Pillow gibt nur die Bilder selbst als Folge von Bildern an, ohne Informationen über die Verzögerungen.
- Manchmal werden Teilbilder falsch überlagert.
Deshalb musste ich nach einem Ersatz suchen. Das
gif2numpy- Modul hat so gehandelt. Es ist für GIF-Funktionen „geschärft“ und bietet Zugriff auf alle technischen Eigenschaften sowohl des Bilds als auch einzelner Frames, einschließlich
GCE . Damit löst er das Problem der Leseverzögerungen.
Wie sich herausstellte, unterstützt gif2numpy die Transparenz überhaupt nicht: Farben werden sofort in drei Kanäle mit einer Bittiefe in Byte konvertiert, ohne die Bittiefe zu berücksichtigen und Farbindizes zu speichern. Glücklicherweise besteht das Modul aus einer Datei, sodass es nicht schwierig war, es in das Projekt aufzunehmen und zu ändern, indem die Farbe
#FE00FE
für Transparenz reserviert wurde.
Das Teilrahmenproblem war nicht trivial zu lösen. gif2numpy
versucht, solche Frames mit dem vorherigen zu überlagern, überprüft jedoch nicht die Overlay-Parameter, weshalb auch nicht immer das richtige Ergebnis angezeigt wird. Um nicht mit Flags
gifsicle
, wird die vorläufige Bildverarbeitung mit
gifsicle
mit dem Schlüssel -
--unoptimize
wird
--unoptimize
- Teilbilder in Vollbilder konvertiert. Gleichzeitig wird die globale Palette verwendet, sodass die transparente Farbe bei Verwendung Ihrer eigenen Rahmenpalette nicht mehr separat verarbeitet werden muss.
Drück mich fester
Quadrate sind gut, aber mit solchen Einschränkungen müssen Sie mehr Vorstellungskraft zeigen, da sich sonst selbst Miniatur-GIFs nicht in das Telegramm „einschleichen“.
Zuerst wurde etwas Ähnliches wie
RLE verwendet : Horizontal benachbarte Quadrate derselben Farbe werden zu einem Rechteck kombiniert.
Als nächstes folgt die Nutzung der Lottie-Funktionen. Da jede Ebene eine beliebige Start- und Endzeit hat, können Sie eine Technik anwenden, die seit langem von Videocodecs und teilweise im GIF selbst verwendet wird: Die Quadrate, die für mehrere Frames an derselben Stelle verbleiben, können zu einer Ebene zusammengeführt werden, während der sich die Anzeige ändert mehrere andere. Was bisher nur für Paare benachbarter Schichten implementiert ist.
Entwicklungspläne
Die Ideen, die hier angewendet werden können, sind in großen Mengen:
Referenzen
- Quellen . Stellenweise beängstigend.
- Der Kanal, auf den ich Pakete erfolgreich konvertierter GIFs hochlade.