Slack GIF Creator - Flexibles Toolkit
Ein Toolkit zum Erstellen animierter GIFs, optimiert für Slack. Es bietet Validatoren für Slacks Einschränkungen, zusammensetzbare Animations-Primitive und optionale Hilfsfunktionen. Setze diese Werkzeuge nach Bedarf ein, um die kreative Vision umzusetzen.
Slacks Anforderungen
Slack hat spezifische Anforderungen an GIFs basierend auf ihrer Verwendung:
Nachrichten-GIFs:
- Max. Größe: ~2 MB
- Optimale Abmessungen: 480x480
- Typische FPS: 15-20
- Farbgrenze: 128-256
- Dauer: 2-5 s
Emoji-GIFs:
- Max. Größe: 64 KB (strenge Grenze)
- Optimale Abmessungen: 128x128
- Typische FPS: 10-12
- Farbgrenze: 32-48
- Dauer: 1-2 s
Emoji-GIFs sind herausfordernd – die 64-KB-Grenze ist streng. Strategien, die helfen:
- Begrenzung auf insgesamt 10-15 Frames
- Maximal 32-48 Farben verwenden
- Designs einfach halten
- Farbverläufe vermeiden
- Dateigröße häufig überprüfen
Toolkit-Struktur
Diese Fähigkeit bietet drei Arten von Werkzeugen:
- Validatoren – Prüfen, ob ein GIF Slacks Anforderungen erfüllt
- Animations-Primitive – Zusammensetzbare Bausteine für Bewegung (Schütteln, Hüpfen, Bewegen, Kaleidoskop)
- Hilfsprogramme – Optionale Funktionen für häufige Bedürfnisse (Text, Farben, Effekte)
Völlige kreative Freiheit bei der Anwendung dieser Werkzeuge ist gegeben.
Kern-Validatoren
Um sicherzustellen, dass ein GIF Slacks Einschränkungen erfüllt, verwende diese Validatoren:
from core.gif_builder import GIFBuilder
# Nachdem du dein GIF erstellt hast, prüfe, ob es die Anforderungen erfüllt
builder = GIFBuilder(width=128, height=128, fps=10)
# ... füge deine Frames nach Belieben hinzu ...
# Speichern und Größe prüfen
info = builder.save('emoji.gif', num_colors=48, optimize_for_emoji=True)
# Die save-Methode warnt automatisch, wenn die Datei die Grenzen überschreitet
# info-dict enthält: size_kb, size_mb, frame_count, duration_seconds
Dateigrößen-Validator:
from core.validators import check_slack_size
# Prüfen, ob GIF die Größenlimits einhält
passes, info = check_slack_size('emoji.gif', is_emoji=True)
# Gibt zurück: (True/False, dict mit Größenangaben)
Dimensions-Validator:
from core.validators import validate_dimensions
# Abmessungen prüfen
passes, info = validate_dimensions(128, 128, is_emoji=True)
# Gibt zurück: (True/False, dict mit Dimensionsangaben)
Vollständige Validierung:
from core.validators import validate_gif, is_slack_ready
# Führe alle Validierungen aus
all_pass, results = validate_gif('emoji.gif', is_emoji=True)
# Oder schnelle Überprüfung
if is_slack_ready('emoji.gif', is_emoji=True):
print("Bereit zum Hochladen!")
Animations-Primitive
Dies sind zusammensetzbare Bausteine für Bewegung. Wende diese auf jedes Objekt in beliebiger Kombination an:
Schütteln
from templates.shake import create_shake_animation
# Ein Emoji schütteln
frames = create_shake_animation(
object_type='emoji',
object_data={'emoji': '😱', 'size': 80},
num_frames=20,
shake_intensity=15,
direction='both' # oder 'horizontal', 'vertical'
)
Hüpfen
from templates.bounce import create_bounce_animation
# Einen Kreis hüpfen lassen
frames = create_bounce_animation(
object_type='circle',
object_data={'radius': 40, 'color': (255, 100, 100)},
num_frames=30,
bounce_height=150
)
Drehen / Rotieren
from templates.spin import create_spin_animation, create_loading_spinner
# Im Uhrzeigersinn drehen
frames = create_spin_animation(
object_type='emoji',
object_data={'emoji': '🔄', 'size': 100},
rotation_type='clockwise',
full_rotations=2
)
# Wackel-Rotation
frames = create_spin_animation(rotation_type='wobble', full_rotations=3)
# Lade-Spinner
frames = create_loading_spinner(spinner_type='dots')
Puls / Herzschlag
from templates.pulse import create_pulse_animation, create_attention_pulse
# Sanfter Puls
frames = create_pulse_animation(
object_data={'emoji': '❤️', 'size': 100},
pulse_type='smooth',
scale_range=(0.8, 1.2)
)
# Herzschlag (Doppelschlag)
frames = create_pulse_animation(pulse_type='heartbeat')
# Aufmerksamkeits-Puls für Emoji-GIFs
frames = create_attention_pulse(emoji='⚠️', num_frames=20)
Ein-/Ausblenden
from templates.fade import create_fade_animation, create_crossfade
# Einblenden
frames = create_fade_animation(fade_type='in')
# Ausblenden
frames = create_fade_animation(fade_type='out')
# Überblendung zwischen zwei Emojis
frames = create_crossfade(
object1_data={'emoji': '😊', 'size': 100},
object2_data={'emoji': '😂', 'size': 100}
)
Zoomen
from templates.zoom import create_zoom_animation, create_explosion_zoom
# Dramatisch hereinzoomen
frames = create_zoom_animation(
zoom_type='in',
scale_range=(0.1, 2.0),
add_motion_blur=True
)
# Herauszoomen
frames = create_zoom_animation(zoom_type='out')
# Explosions-Zoom
frames = create_explosion_zoom(emoji='💥')
Explodieren / Zersplittern
from templates.explode import create_explode_animation, create_particle_burst
# Stoßexplosion
frames = create_explode_animation(
explode_type='burst',
num_pieces=25
)
# Zersplitterungseffekt
frames = create_explode_animation(explode_type='shatter')
# In Partikel auflösen
frames = create_explode_animation(explode_type='dissolve')
# Partikelausbruch
frames = create_particle_burst(particle_count=30)
Wackeln / Schwingen
from templates.wiggle import create_wiggle_animation, create_excited_wiggle
# Wackelpudding-Bewegung
frames = create_wiggle_animation(
wiggle_type='jello',
intensity=1.0,
cycles=2
)
# Wellenbewegung
frames = create_wiggle_animation(wiggle_type='wave')
# Aufgeregtes Wackeln für Emoji-GIFs
frames = create_excited_wiggle(emoji='🎉')
Gleiten
from templates.slide import create_slide_animation, create_multi_slide
# Von links hereingleiten mit Überschwingen
frames = create_slide_animation(
direction='left',
slide_type='in',
overshoot=True
)
# Hinübergleiten
frames = create_slide_animation(direction='left', slide_type='across')
# Mehrere Objekte nacheinander hereingleiten lassen
objects = [
{'data': {'emoji': '🎯', 'size': 60}, 'direction': 'left', 'final_pos': (120, 240)},
{'data': {'emoji': '🎪', 'size': 60}, 'direction': 'right', 'final_pos': (240, 240)}
]
frames = create_multi_slide(objects, stagger_delay=5)
Umdrehen
from templates.flip import create_flip_animation, create_quick_flip
# Horizontales Umdrehen zwischen zwei Emojis
frames = create_flip_animation(
object1_data={'emoji': '😊', 'size': 120},
object2_data={'emoji': '😂', 'size': 120},
flip_axis='horizontal'
)
# Vertikales Umdrehen
frames = create_flip_animation(flip_axis='vertical')
# Schnelles Umdrehen für Emoji-GIFs
frames = create_quick_flip('👍', '👎')
Morphen / Transformieren
from templates.morph import create_morph_animation, create_reaction_morph
# Überblendungs-Morph
frames = create_morph_animation(
object1_data={'emoji': '😊', 'size': 100},
object2_data={'emoji': '😂', 'size': 100},
morph_type='crossfade'
)
# Skalierungs-Morph (schrumpfen, während andere wächst)
frames = create_morph_animation(morph_type='scale')
# Spin-Morph (wie eine 3D-Drehung)
frames = create_morph_animation(morph_type='spin_morph')
Bewegungseffekt
from templates.move import create_move_animation
# Lineare Bewegung
frames = create_move_animation(
object_type='emoji',
object_data={'emoji': '🚀', 'size': 60},
start_pos=(50, 240),
end_pos=(430, 240),
motion_type='linear',
easing='ease_out'
)
# Bogenbewegung (parabelförmige Flugbahn)
frames = create_move_animation(
object_type='emoji',
object_data={'emoji': '⚽', 'size': 60},
start_pos=(50, 350),
end_pos=(430, 350),
motion_type='arc',
motion_params={'arc_height': 150}
)
# Kreisbewegung
frames = create_move_animation(
object_type='emoji',
object_data={'emoji': '🌍', 'size': 50},
motion_type='circle',
motion_params={
'center': (240, 240),
'radius': 120,
'angle_range': 360 # voller Kreis
}
)
# Wellenbewegung
frames = create_move_animation(
motion_type='wave',
motion_params={
'wave_amplitude': 50,
'wave_frequency': 2
}
)
# Oder verwende Low-Level-Easing-Funktionen
from core.easing import interpolate, calculate_arc_motion
for i in range(num_frames):
t = i / (num_frames - 1)
x = interpolate(start_x, end_x, t, easing='ease_out')
# Oder: x, y = calculate_arc_motion(start, end, height, t)
Kaleidoskop-Effekt
from templates.kaleidoscope import apply_kaleidoscope, create_kaleidoscope_animation
# Auf einen einzelnen Frame anwenden
kaleido_frame = apply_kaleidoscope(frame, segments=8)
# Oder animiertes Kaleidoskop erstellen
frames = create_kaleidoscope_animation(
base_frame=my_frame, # oder None für Demo-Muster
num_frames=30,
segments=8,
rotation_speed=1.0
)
# Einfache Spiegeleffekte (schneller)
from templates.kaleidoscope import apply_simple_mirror
mirrored = apply_simple_mirror(frame, mode='quad') # 4-fach-Spiegelung
# Modi: 'horizontal', 'vertical', 'quad', 'radial'
Um Primitive frei zusammenzusetzen, folge diesen Mustern:
# Beispiel: Hüpfen + Schütteln für Aufpralleffekt
for i in range(num_frames):
frame = create_blank_frame(480, 480, bg_color)
# Hüpfbewegung
t_bounce = i / (num_frames - 1)
y = interpolate(start_y, ground_y, t_bounce, 'bounce_out')
# Schütteln beim Aufprall (wenn y den Boden erreicht)
if y >= ground_y - 5:
shake_x = math.sin(i * 2) * 10
x = center_x + shake_x
else:
x = center_x
draw_emoji(frame, '⚽', (x, y), size=60)
builder.add_frame(frame)
Hilfsprogramme
Dies sind optionale Hilfsmittel für häufige Bedürfnisse. Verwende, modifiziere oder ersetze diese durch benutzerdefinierte Implementierungen nach Bedarf.
GIF-Builder (Zusammenbau & Optimierung)
from core.gif_builder import GIFBuilder
# Erstelle Builder mit deinen gewählten Einstellungen
builder = GIFBuilder(width=480, height=480, fps=20)
# Frames hinzufügen (wie auch immer du sie erstellt hast)
for frame in my_frames:
builder.add_frame(frame)
# Mit Optimierung speichern
builder.save('output.gif',
num_colors=128,
optimize_for_emoji=False)
Hauptfunktionen:
- Automatische Farbquantisierung
- Entfernung doppelter Frames
- Größenwarnungen für Slack-Grenzen
- Emoji-Modus (aggressive Optimierung)
Textdarstellung
Bei kleinen GIFs wie Emojis ist die Lesbarkeit von Text eine Herausforderung. Eine gängige Lösung besteht darin, Umrisse hinzuzufügen:
from core.typography import draw_text_with_outline, TYPOGRAPHY_SCALE
# Text mit Umriss (hilft bei der Lesbarkeit)
draw_text_with_outline(
frame, "BONK!",
position=(240, 100),
font_size=TYPOGRAPHY_SCALE['h1'], # 60px
text_color=(255, 68, 68),
outline_color=(0, 0, 0),
outline_width=4,
centered=True
)
Um eine benutzerdefinierte Textdarstellung zu implementieren, verwende PILs ImageDraw.text(), was für größere GIFs gut funktioniert.
Farbmanagement
Professionell aussehende GIFs verwenden oft abgestimmte Farbpaletten:
from core.color_palettes import get_palette
# Eine vorgefertigte Palette holen
palette = get_palette('vibrant') # oder 'pastel', 'dark', 'neon', 'professional'
bg_color = palette['background']
text_color = palette['primary']
accent_color = palette['accent']
Um direkt mit Farben zu arbeiten, verwende RGB-Tupel – was immer für den Anwendungsfall funktioniert.
Visuelle Effekte
Optionale Effekte für wirkungsvolle Momente:
from core.visual_effects import ParticleSystem, create_impact_flash, create_shockwave_rings
# Partikelsystem
particles = ParticleSystem()
particles.emit_sparkles(x=240, y=200, count=15)
particles.emit_confetti(x=240, y=200, count=20)
# Aktualisieren und rendern in jedem Frame
particles.update()
particles.render(frame)
# Blitzeffekt
frame = create_impact_flash(frame, position=(240, 200), radius=100)
# Schockwellenringe
frame = create_shockwave_rings(frame, position=(240, 200), radii=[30, 60, 90])
Easing-Funktionen
Sanfte Bewegung verwendet Easing statt linearer Interpolation:
from core.easing import interpolate
# Objekt fällt (beschleunigt)
y = interpolate(start=0, end=400, t=progress, easing='ease_in')
# Objekt landet (verlangsamt)
y = interpolate(start=0, end=400, t=progress, easing='ease_out')
# Hüpfen
y = interpolate(start=0, end=400, t=progress, easing='bounce_out')
# Überschwingen (elastisch)
scale = interpolate(start=0.5, end=1.0, t=progress, easing='elastic_out')
Verfügbare Easings: linear, ease_in, ease_out, ease_in_out, bounce_out, elastic_out, back_out (Überschwingen) und mehr in core/easing.py.
Frame-Komposition
Grundlegende Zeichenwerkzeuge, falls benötigt:
from core.frame_composer import (
create_gradient_background, # Farbverlaufshintergründe
draw_emoji_enhanced, # Emoji mit optionalem Schatten
draw_circle_with_shadow, # Formen mit Tiefe
draw_star # 5-zackige Sterne
)
# Farbverlaufshintergrund
frame = create_gradient_background(480, 480, top_color, bottom_color)
# Emoji mit Schatten
draw_emoji_enhanced(frame, '🎉', position=(200, 200), size=80, shadow=True)
Optimierungsstrategien
Wenn dein GIF zu groß ist:
Für Nachrichten-GIFs (>2 MB):
- Reduziere Frames (niedrigere FPS oder kürzere Dauer)
- Reduziere Farben (128 → 64 Farben)
- Reduziere Abmessungen (480x480 → 320x320)
- Aktiviere die Entfernung doppelter Frames
Für Emoji-GIFs (>64 KB) – sei aggressiv:
- Begrenze auf insgesamt 10-12 Frames
- Verwende maximal 32-40 Farben
- Vermeide Farbverläufe (einfarbige Flächen komprimieren besser)
- Vereinfache das Design (weniger Elemente)
- Verwende
optimize_for_emoji=Truein der save-Methode
Beispiel-Kompositionsmuster
Einfache Reaktion (Pulsierend)
builder = GIFBuilder(128, 128, 10)
for i in range(12):
frame = Image.new('RGB', (128, 128), (240, 248, 255))
# Pulsierende Skalierung
scale = 1.0 + math.sin(i * 0.5) * 0.15
size = int(60 * scale)
draw_emoji_enhanced(frame, '😱', position=(64-size//2, 64-size//2),
size=size, shadow=False)
builder.add_frame(frame)
builder.save('reaction.gif', num_colors=40, optimize_for_emoji=True)
# Validieren
from core.validators import check_slack_size
check_slack_size('reaction.gif', is_emoji=True)