Em vez de mil palavras ...O xZibit também está feliz, porque aqui os GIFs são inseridos em adesivos para serem inseridos nos GIFs do KDPV!E agora sobre os detalhes da implementação.
Tudo começou com uma discussão no bate-papo do desenvolvedor do Telegram sobre o próximo recurso:
![Bohdan Horbeshko, [04/04/19 20:21] Hmm, mas o bot provavelmente só aceitará gifs e depois converterá ... | Vitaly, [19/04/19 20:22] do gif para Jason? Eu teria olhado :))) | Bohdan Horbeshko, [04.07.19 20:22] E por que não? Há um editor de modelo do PlayCanvas no JSON. | Vitaly, [19/04/04 20:23] e como está o gif? exportar pixel por pixel? :) Bohdan Horbeshko, [04/04/19 20:24] Obviamente, o mundo da TI viu e não tolerará tais distorções.](https://habrastorage.org/webt/zu/s5/x1/zus5x1ydd89sejezp98ztbnygto.png)
Um homem disse - um homem fez! O primeiro protótipo em Pillow e svgwrite, analisando GIFs em pixels e convertendo-os em quadrados de vetor com visualizações em SVG, foi gravado em um dia de folga.
A diversão começou ainda mais ...
JSON é um formato aberto, eles disseram ...
Até agora, com os formatos no Telegram, eles continuavam enganando. Suporte feito para animações GIF - na verdade, elas são convertidas em vídeo MP4. Suporte feito para adesivos - eles são enviados para PNG, mas convertidos em WebP. Desta vez, tudo é mais honesto: isso na entrada e depois na saída.
Para adesivos animados, o Telegram não usa GIFs, vídeos ou até mesmo alguns formatos de gráficos vetoriais bem estabelecidos, como SVG, ou Deus proíba Cthulhu! Flash. Ele usa um formato newfangled que surgiu sob a asa do Airbnb - Lottie. Até agora, ele tinha alguma fama entre os desenvolvedores de dispositivos móveis, mas graças ao Telegram, ele pode ganhar mais popularidade.
Em essência, os arquivos Lottie são projetos Adobe After Effects serializados em JSON que maximizam todos os recursos deste programa. Com a tela, infelizmente,
nem tudo é tão róseo . Embora existam muitas implementações "oficiais" prontas da biblioteca para renderizar Lottie, apenas para as plataformas cobertas pelo Telegram: Android, iOS, Qt e Web - apenas parte dos recursos do formato é implementada em todas elas. O Telegram foi ainda mais longe e
limitou a lista de recursos suportados, bem como “veio” com seu próprio formato, que difere do Lottie usual apenas por
"tgs": 1
o GZip e o parâmetro
"tgs": 1
. Acho que sei onde Denis Popov está trabalhando agora! :-)
E se tudo estiver muito bom com a documentação para bibliotecas para plataformas diferentes, então, infelizmente, não foi possível encontrar pelo menos alguma descrição do dispositivo de formato - apenas o
esquema JSON nas fontes da lottie-web. Eu tive que mexer nas animações existentes para entender os conceitos gerais do formato. Também houve discrepâncias entre arquivos reais e o esquema: em particular, nas
camadas do tipo 4 , de acordo com o esquema, os objetos aninhados são armazenados na propriedade
"it"
- no entanto, em arquivos reais, a chave é chamada de
"shapes"
e
"it"
não funciona.
As nuances esclarecidas do formato:
- Um arquivo consiste em camadas. Ao contrário do GIF, aqui cada camada pode ter um horário de início e término arbitrário para a exibição. Várias transformações podem ser aplicadas à camada (mais precisamente, é necessário ): escala, rotação, alteração da transparência, etc. As camadas podem até ser tridimensionais (proibidas para o telegrama).
- Uma camada consiste em "formas". Eles têm muitos tipos, alguns não podem ser usados no telegrama. Na prática, para que uma camada apareça, ela deve incluir três formas: um caminho (nas animações concluídas, geralmente é o tipo
"sh"
- curvas de Bezier; o conversor até agora usa apenas o tipo "rc"
- retângulos), o preenchimento (o tipo "fl"
) e a transformação ( digite "tr"
). - Você pode até incluir elementos raster, criar camadas de texto e estabelecer relacionamentos entre os parâmetros de camada e forma por meio de expressões. Todos esses brindes também são proibidos no Telegram.
O primeiro problema segue diretamente daqui:
redundância . Embora os valores padrão para os parâmetros de transformação tenham sido adicionados recentemente ao esquema JSON, eles não são implementados nas bibliotecas. Portanto, perguntar explicitamente ainda é necessário.
Parece que isso não é um problema? Mesmo um simples GZip faz um bom trabalho na compactação de dados flagrantemente repetitivos, e 1 MB de JSON bruto se transforma magicamente em algumas dezenas de kilobytes, que silenciosamente atingem o limite estabelecido de 64 kB. Lá estava!
Eu carrego, o que significa uma animação gordinha que exibe calmamente web-lottie no Telegram - e aqui, em vez de uma pixel art condicionalmente bonita, o olhar estático e embaçado para mim é o seguinte:

O que é isso ?! Mas aconteceu que há claramente um
limite não especificado
de 1 MB nos dados descompactados. Um representante da equipe do Telegram
confirmou rapidamente e anunciou o próximo aumento no limite para 2 MB.
Mesmo que resolvam esses problemas, os adesivos que ultrapassam 1 MB de dados não compactados e não contêm transformações serão inacessíveis aos usuários de versões mais antigas do Telegram. Portanto, provavelmente terá que cumprir as restrições no futuro.
Transparência é importante.
O Pillow, juntamente com o OpenCV, pode ser chamado de padrão da indústria para processamento de imagens em Python. Além disso, também é bem aprimorado para os recursos de GIF: suporta cores indexadas e dá acesso à paleta. Ele suporta a conversão de um mapa de pixels em uma matriz NumPy, o que é importante para o processamento produtivo. Até coleta estatísticas sobre cores! Mas também havia desvantagens:
- Não havia uma maneira documentada de obter o índice de cores transparente. Eu tive que assumir como solução temporária que a cor transparente é a mais comum, mas em GIFs reais esse nem sempre é o caso.
- A mesma coisa com um atraso entre os quadros: Pillow fornece apenas os próprios quadros como uma sequência de imagens, sem informações sobre os atrasos.
- Às vezes, os quadros parciais são sobrepostos incorretamente.
Portanto, eu tive que procurar uma substituição. O módulo
gif2numpy agiu como ele. Ele é "aprimorado" para os recursos GIF e fornece acesso a todas as propriedades técnicas da imagem e dos quadros individuais, incluindo o
GCE . Assim, ele resolve o problema de atrasos na leitura.
A transparência, como se viu, não é totalmente compatível com o gif2numpy: as cores são imediatamente convertidas em três canais com profundidade de bits em bytes, sem levar em consideração a profundidade de bits e salvar os índices de cores. Felizmente, o módulo consiste em um arquivo, por isso não foi difícil incluí-lo no projeto e modificá-lo, reservando a cor
#FE00FE
para transparência.
O problema do quadro parcial não foi trivial para resolver. O gif2numpy
tenta sobrepor esses quadros ao anterior, no entanto, ele não verifica os parâmetros de sobreposição, o que nem sempre fornece o resultado correto. Para não mexer nas bandeiras, o processamento preliminar de imagens usando
gifsicle
com a tecla
--unoptimize
é
--unoptimize
- converte quadros parciais em quadros completos. E, ao mesmo tempo, os leva a usar a paleta global, o que eliminou a necessidade de processar separadamente a cor transparente ao usar sua própria paleta de quadros.
Aperte-me com mais força
Os quadrados são bons, mas com essas limitações, você precisa mostrar mais imaginação; caso contrário, até GIFs em miniatura não serão "arrastados" para o telegrama.
Algo semelhante ao
RLE foi usado primeiro : quadrados adjacentes horizontalmente da mesma cor são combinados em um retângulo.
A seguir, a exploração dos recursos da Lottie. Como cada camada possui um horário de início e término arbitrários, é possível aplicar uma técnica usada há muito tempo pelos codecs de vídeo e parcialmente no próprio GIF: os quadrados que permanecem no mesmo local por vários quadros podem ser mesclados em uma camada, durante a qual as alterações na exibição vários outros. Até agora, implementado apenas para pares de camadas adjacentes.
Planos de desenvolvimento
As idéias que podem ser aplicadas aqui são em massa:
Referências
- Fontes . Assustador em alguns lugares.
- O canal no qual eu carrego pacotes de GIFs convertidos com êxito.