Animiertes GIF
Drei Werkzeuge, ein Kernmodul. Wähle die Route passend zur Eingabe.
| Eingabe | Werkzeug | Bewegung |
|---|---|---|
| Text-Frames mit ANSI-Farben | bin/ascii_gif.py | Frame-Sequenz |
| Ordner mit Fotos oder Bildern | bin/pics_gif.py | Halten, Überblendung, Ken Burns |
| SVG- oder HTML-Animation | bin/svg_gif.py | SMIL, CSS oder voreingestellte Drehung/Puls/Fade |
Alle Routen teilen bin/gifkit.py: eine Palette über die gesamte Schleife, 10‑ms‑Timing‑Raster, identische aufeinanderfolgende Frames werden zu längeren Verzögerungen zusammengefasst, atomares Schreiben, Rücklese-Validierung.
Abhängigkeiten
Pillow wird benötigt. SVG und HTML benötigen Node mit Playwright und einer Chromium-Headless-Shell.
python -c "import PIL; print(PIL.__version__)"
node -e "require('playwright')"
npx playwright install chromium --only-shell
Jedes Werkzeug gibt bei fehlender Abhängigkeit oder Eingabe eine Zeile FAIL ... auf stderr aus und beendet sich mit Exit‑Code 1. Wiederhole es nicht mit denselben Argumenten.
Arbeitsablauf
- Wähle die Route aus der Tabelle. Lies den zugehörigen Abschnitt unten.
- Führe das Werkzeug mit einem expliziten Ausgabepfad innerhalb des aktuellen Projekts aus. Schreibe nicht in ein System-Temporärverzeichnis oder auf den Desktop.
- Behalte die ausgegebene Zusammenfassung: Frame-Anzahl, Dauer, Pixelgröße. Ein gedruckter Pfad ist ein validiertes GIF.
- Bei visueller Arbeit öffne das GIF oder verwende
--preview preview.pngund überprüfe das Standbild, bevor du Bericht erstattest. - Gib den absoluten Pfad sowie die relevanten Einstellungen an: fps, Größe, Dauer, Modus.
ASCII-Route
Die Eingabe ist eine Textdatei. Frames werden durch eine Zeile mit ausschließlich --- getrennt; optional folgt nach dem Trennzeichen eine Verzögerung in ms: --- 250. ANSI-SGR-Farben werden beachtet: 30‑37, 90‑97, 38;5;n und 38;2;r;g;b. Ein Verzeichnis mit .txt-Dateien wird als ein Frame pro Datei gelesen, sortiert nach Name.
python bin/ascii_gif.py frames.txt -o projekt/loader.gif --size 28 --delay 120
python bin/ascii_gif.py frames/ -o projekt/loader.gif --preview projekt/loader.png
--fontmuss eine monospace TTF oder TTC sein; gängige Monospace-Schriftarten werden automatisch erkannt, wenn diese Option weggelassen wird.--widthund--heightlegen die Leinwand fest und zentrieren das Textraster. Gib beide oder keine an. Verwende dies, um eine Größe über mehrere Beispiele hinweg anzugleichen.--fgund--bgstandardmäßig heller Text auf nahezu schwarzer Leinwand.--delayist die standardmäßige Frame-Verzögerung; Trennzeichen-Verzögerungen überschreiben sie pro Frame.- Halte Frames auf etwa 120 Spalten und 40 Zeilen; größere Leinwände erzeugen lange GIFs.
Bildordner-Route
Dateien werden natürlich sortiert (pic-2 vor pic-10), EXIF-rotatiert und an eine einheitliche Leinwand angepasst.
python bin/pics_gif.py fotos/ -o projekt/reel.gif --mode kenburns --fps 12 --hold 1.2 --transition 0.5 --width 800
python bin/pics_gif.py fotos/ -o projekt/reel.gif --mode sequence --fps 10 --hold 0.8 --fit contain --bg "#101010"
sequencehält jedes Bild;crossfadeüberblendet zwischen Bildern;kenburnszoomt jedes Bild langsam heran, abwechselnde Richtung.--widthsetzt die Leinwand;--heightstandardmäßig das Seitenverhältnis des ersten Bildes.--fit coverschneidet zu, um die Leinwand zu füllen,containfüllt mit--bgauf.--holdist die Anzeigedauer pro Bild in Sekunden,--transitiondie Überblendungsdauer,--zoomder Endzoom bei Ken Burns.- Ein Ordner mit 100 Fotos bei 800 px und 12 fps erzeugt eine große Datei; reduziere zuerst Breite oder fps.
SVG- und HTML-Route
Das Werkzeug bettet .svg in eine Seite mit dem angeforderten Viewport ein oder öffnet .html direkt, pausiert dann und sucht jede Animation zu expliziten Zeitpunkten vor jedem Screenshot auf. Frames hängen nicht von der Wanduhrzeit ab.
python bin/svg_gif.py logo.svg -o projekt/logo.gif --duration 3 --fps 15
python bin/svg_gif.py logo.svg -o projekt/logo.gif --animate rotate --selector "#mark" --duration 2 --background "#0b0d12"
python bin/svg_gif.py seite.html -o projekt/seite.gif --width 960 --height 540 --duration 4 --fps 12
- Ohne
--animatemuss das SVG oder die Seite bereits durch SMIL oder CSS animieren. Statische Zeichnungen benötigen eine Voreinstellung. - Voreinstellungen:
rotate,pulse,fade, angewendet auf das SVG‑Root oder auf--selector. --widthund--heightstandardmäßig diewidth/heightoderviewBoxdes SVG.--dpr 2erfasst mit doppelter Viewport‑Auflösung für schärferen Text; das GIF ist dann doppelt so groß.- Von JS gesteuerte Canvas- oder WebGL-Seiten werden von diesem Werkzeug nicht angetrieben. Verwende eine Seite, die einen Frame‑Hook bereitstellt, oder rendere Frames vorab und erstelle das GIF mit gifkit.
Gemeinsame Optionen
--colorsbis zu 255. Reduziere sie nur, wenn die Palette einfach ist oder die Datei kleiner werden soll.--dither noneist korrekt für flache Grafiken und Text;floydhilft bei Verläufen und Fotos.--loop 0wiederholt endlos; jeder andere Wert wiederholt diese Anzahl.--preview PFADschreibt ein PNG‑Standbild des ersten Frames.- Die Ausgabe ist deterministisch bei gleicher Eingabe, gleichen Einstellungen und gleicher Toolchain.
Benutzerdefinierte Frames
Jede Frame-Sequenz kann denselben Kern verwenden. Frames müssen RGB und gleich groß sein; Verzögerungen in ms auf dem 10‑ms‑Raster.
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, "projekt/verlauf.gif", [100] * 12)
write_gif erstellt eine Palette, fasst identische aufeinanderfolgende Frames zusammen, schreibt atomar und validiert das Ergebnis. Verwende diese Route für Datenanimationen, generierte Diagramme oder andere Frames, die von diesen Routen nicht abgedeckt werden.
Vertrag
- Das Werkzeug schreibt in
<name>.tmp.gifim Ausgabeverzeichnis, validiert Frame-Anzahl, Gesamtdauer und Pixelgröße durch Rücklesen der Datei und benennt sie dann um. Ein Fehler entfernt die temporäre Datei und hinterlässt kein unvollständiges Ziel. - Das GIF verwendet eine einzige Palette für jeden Frame, sodass Farben nicht flackern können.
- Identische aufeinanderfolgende Frames werden zu einem Frame mit längerer Verzögerung zusammengefasst; die ausgegebene Frame-Anzahl ist die gespeicherte Anzahl.
- Verzögerungen liegen auf dem 10‑ms‑GIF‑Raster und betragen mindestens 20 ms.
Überprüfung
Routenfunktionstests befinden sich im Quellverzeichnis. Vom Repository-Stammverzeichnis:
python tools/check.py
Jeder Test gibt eine Zeile PASS, SKIP oder FAIL aus. Fehlende optionale Abhängigkeiten werden standardmäßig übersprungen; --strict erfordert jede Route. Die Tests erzeugen Testdaten unter scratch/checks und durchsuchen das Repository außerdem nach Geheimnissen, absoluten Pfaden, nicht-ASCII-Text und CRLF-Zeilenenden.
Grenzen
- GIF ist 8‑Bit‑indiziert und auf 256 Farben begrenzt; Fotos zeigen ohne Dithering Banding.
- Betrachter kürzen kurze Verzögerungen; halte Frame-Verzögerungen bei 20 ms oder mehr.
- Lange, hochauflösende, truecolor-Sequenzen sind besser als APNG oder WebM aufgehoben. Sage dies, wenn Qualität gewünscht wird.
- Der Speicherverbrauch wächst mit Frame-Anzahl und Leinwandgröße; die Werkzeuge halten alle Frames während der Palettenberechnung im Speicher.
- Die Glyphenabdeckung hängt von der gewählten Schriftart ab; fehlende Rahmen- oder Blockglyphen fallen auf leere Kästchen zurück.
Siehe references/animated-gif-considerations.md für Formateinschränkungen und die Begründung dieser Standardeinstellungen.
Dateien
bin/gifkit.py- Palette, Timing, Zusammenführung, atomares Schreiben, Validierung.bin/ascii_gif.py- ANSI-Text-Frames zu GIF.bin/pics_gif.py- Bildordner zu GIF.bin/svg_gif.py- SVG/HTML-Animation zu GIF.bin/render_frames.cjs- Playwright-Frame-Erfassungshelfer.references/animated-gif-considerations.md- Formatanmerkungen.
Repository-Überprüfungen und Beispielgenerierung befinden sich in tools/, außerhalb der installierten Skill-Nutzlast.