GIF animé
Trois outils, un cœur d'assemblage. Choisissez la route qui correspond à l'entrée.
| Entrée | Outil | Mouvement |
|---|---|---|
| Trames de texte avec couleurs ANSI | bin/ascii_gif.py | séquence de trames |
| Dossier de photos ou d'images | bin/pics_gif.py | maintien, fondu, Ken Burns |
| Animation SVG ou HTML | bin/svg_gif.py | SMIL, CSS, ou préréglage rotate/pulse/fade |
Toutes les routes partagent bin/gifkit.py : une palette sur toute la boucle, grille de timing de 10 ms, trames consécutives identiques fusionnées en délais plus longs, écriture atomique, vérification par relecture.
Dépendances
Pillow est requis. SVG et HTML nécessitent Node avec Playwright et un shell Chromium headless.
python -c "import PIL; print(PIL.__version__)"
node -e "require('playwright')"
npx playwright install chromium --only-shell
Chaque outil affiche une ligne FAIL ... sur stderr et se termine avec le code 1 si une dépendance ou une entrée manque. Ne réessayez pas avec les mêmes arguments.
Flux de travail
- Choisissez la route dans le tableau. Lisez la section correspondante ci-dessous.
- Exécutez l'outil avec un chemin de sortie explicite à l'intérieur du projet sur lequel vous travaillez. N'écrivez pas dans un répertoire temporaire système ou sur le Bureau.
- Conservez le résumé imprimé : nombre de trames, durée, taille en pixels. Un chemin imprimé est un GIF vérifié.
- Pour un travail visuel, ouvrez le GIF ou écrivez
--preview preview.pngpuis inspectez cette image fixe avant de faire un rapport. - Rapportez le chemin absolu ainsi que les paramètres importants : fps, taille, durée, mode.
Route ASCII
L'entrée est un fichier texte. Les trames sont séparées par une ligne contenant uniquement --- ; un délai optionnel en ms suit le séparateur : --- 250. Les couleurs SGR ANSI sont respectées : 30-37, 90-97, 38;5;n et 38;2;r;g;b. Un répertoire de fichiers .txt est lu comme une trame par fichier, trié par nom.
python bin/ascii_gif.py frames.txt -o project/loader.gif --size 28 --delay 120
python bin/ascii_gif.py frames/ -o project/loader.gif --preview project/loader.png
--fontdoit être un TTF ou TTC monospace ; les polices monospace courantes sont détectées automatiquement lorsqu'elle est omise.--widthet--heightfixent le canevas et centrent la grille de texte. Donnez les deux ou aucun. Utilisez ceci pour correspondre à une taille sur plusieurs échantillons.--fget--bgpar défaut : texte clair sur fond quasi noir.--delayest le délai de trame par défaut ; les délais de séparateur le remplacent par trame.- Limitez les trames à environ 120 colonnes et 40 lignes ; des canevas plus grands produisent des GIF longs.
Route dossier d'images
Les fichiers sont triés naturellement (pic-2 avant pic-10), pivotés selon EXIF, et adaptés à un seul canevas.
python bin/pics_gif.py photos/ -o project/reel.gif --mode kenburns --fps 12 --hold 1.2 --transition 0.5 --width 800
python bin/pics_gif.py photos/ -o project/reel.gif --mode sequence --fps 10 --hold 0.8 --fit contain --bg "#101010"
sequencemaintient chaque image ;crossfadefond les images entre elles ;kenburnseffectue un zoom lent sur chaque image, en alternant la direction.--widthdéfinit le canevas ;--heightpar défaut suit le rapport d'aspect de la première image.--fit coverrecadre pour remplir,containajoute des bords avec--bg.--holdest le temps en secondes par image,--transitionla durée de fondu en secondes,--zoomle zoom final de Ken Burns.- Un dossier de 100 photos à 800 px et 12 fps produit un fichier volumineux ; réduisez d'abord la largeur ou les fps.
Route SVG et HTML
L'outil encapsule le .svg dans une page à la fenêtre demandée, ou ouvre directement le .html, puis fait une pause et cherche chaque animation à des temps explicites avant chaque capture d'écran. Les trames ne dépendent pas du temps réel.
python bin/svg_gif.py logo.svg -o project/logo.gif --duration 3 --fps 15
python bin/svg_gif.py logo.svg -o project/logo.gif --animate rotate --selector "#mark" --duration 2 --background "#0b0d12"
python bin/svg_gif.py page.html -o project/page.gif --width 960 --height 540 --duration 4 --fps 12
- Sans
--animate, le SVG ou la page doit déjà animer via SMIL ou CSS. Les dessins statiques nécessitent un préréglage. - Préréglages :
rotate,pulse,fade, appliqués à la racine SVG ou à--selector. --widthet--heightpar défaut correspondent auxwidth/heightouviewBoxdu SVG.--dpr 2capture à double résolution de la fenêtre, pour un texte plus net ; le GIF est alors deux fois plus grand en pixels.- Les pages utilisant JS (toile WebGL) ne sont pas pilotées par cet outil. Utilisez une page qui expose un hook de trame, ou pré-rendez les trames et assemblez-les avec gifkit.
Options partagées
--colorsjusqu'à 255. Réduisez-le seulement si la palette est simple ou si le fichier doit être plus petit.--dither noneest correct pour les illustrations plates et le texte ;floydaide pour les dégradés et les photos.--loop 0boucle infiniment ; toute autre valeur répète ce nombre de fois.--preview PATHécrit un PNG de la première trame.- La sortie est déterministe pour les mêmes entrée, paramètres et chaîne d'outils.
Trames personnalisées
Toute séquence de trames peut utiliser le même cœur. Les trames doivent être RGB et de même taille ; les délais sont en ms sur la grille de 10 ms.
import sys
sys.path.insert(0, "bin")
import gifkit
from PIL import Image
frames = [Image.new("RGB", (320, 180), (n * 20, 40, 90)) for n in range(12)]
gifkit.write_gif(frames, "project/gradient.gif", [100] * 12)
write_gif construit une palette, fusionne les trames consécutives identiques, écrit atomiquement et vérifie le résultat. Utilisez cette route pour des animations de données, des diagrammes générés ou toutes trames non couvertes par ces routes.
Contrat
- L'outil écrit dans
<nom>.tmp.gifdans le répertoire de sortie, vérifie le nombre de trames, la somme des durées et la taille en pixels en relisant le fichier, puis le renomme. Un échec supprime le fichier temporaire et ne laisse pas de cible partielle. - Le GIF utilise une palette unique pour chaque trame, donc les couleurs ne peuvent pas scintiller.
- Les trames consécutives identiques sont fusionnées en une seule trame avec un délai plus long ; le nombre de trames affiché est le nombre stocké.
- Les délais sont sur la grille GIF de 10 ms et sont d'au moins 20 ms.
Vérification
Les vérifications de route vivent dans le dépôt source. Depuis la racine du dépôt :
python tools/check.py
Chaque vérification affiche une ligne PASS, SKIP ou FAIL. Les dépendances optionnelles manquantes sont ignorées par défaut ; --strict exige chaque route. Les vérifications génèrent des fichiers de test sous scratch/checks et analysent également le dépôt pour les secrets, chemins absolus, texte non ASCII et fins de ligne CRLF.
Limites
- Le GIF est indexé en 8 bits et plafonne à 256 couleurs ; les photos présentent des bandes sans tramage.
- Les lecteurs limitent les délais courts ; maintenez les délais de trame à 20 ms ou plus.
- Les séquences longues, à fps élevé, en couleurs réelles sont mieux adaptées au format APNG ou WebM. Dites-le lorsque la qualité est demandée.
- La mémoire croît avec le nombre de trames et la taille du canevas ; les outils conservent toutes les trames pendant la construction de la palette.
- La couverture des glyphes ASCII dépend de la police choisie ; les glyphes de boîte ou de bloc manquants retombent sur des boîtes vides.
Voir references/animated-gif-considerations.md pour les contraintes de format et les raisons de ces valeurs par défaut.
Fichiers
bin/gifkit.py- palette, timing, fusion, écriture atomique, vérification.bin/ascii_gif.py- trames de texte ANSI en GIF.bin/pics_gif.py- dossier d'images en GIF.bin/svg_gif.py- animation SVG/HTML en GIF.bin/render_frames.cjs- assistant de capture de trames Playwright.references/animated-gif-considerations.md- notes de format.
Les vérifications de dépôt et la génération d'échantillons se trouvent dans tools/, en dehors de la charge utile de la compétence installée.