Créateur de GIF Slack
Un toolkit fournissant des utilitaires et des connaissances pour créer des GIFs animés optimisés pour Slack.
Exigences Slack
Dimensions :
- GIFs emoji : 128x128 (recommandé)
- GIFs message : 480x480
Paramètres :
- FPS : 10-30 (plus bas = fichier plus petit)
- Couleurs : 48-128 (moins = fichier plus petit)
- Durée : Rester sous 3 secondes pour les GIFs emoji
Workflow principal
from core.gif_builder import GIFBuilder
from PIL import Image, ImageDraw
# 1. Créer le builder
builder = GIFBuilder(width=128, height=128, fps=10)
# 2. Générer les frames
for i in range(12):
frame = Image.new('RGB', (128, 128), (240, 248, 255))
draw = ImageDraw.Draw(frame)
# Dessiner votre animation avec les primitives PIL
# (cercles, polygones, lignes, etc.)
builder.add_frame(frame)
# 3. Sauvegarder avec optimisation
builder.save('output.gif', num_colors=48, optimize_for_emoji=True)
Dessiner des graphiques
Travailler avec des images uploadées par l'utilisateur
Si un utilisateur upload une image, considérez s'il veut :
- L'utiliser directement (par exemple, "anime ça", "divise ça en frames")
- L'utiliser comme inspiration (par exemple, "fais quelque chose comme ça")
Charger et travailler avec des images avec PIL :
from PIL import Image
uploaded = Image.open('file.png')
# Utiliser directement, ou juste comme référence pour les couleurs/le style
Dessiner à partir de zéro
Quand dessiner des graphiques à partir de zéro, utiliser les primitives PIL ImageDraw :
from PIL import ImageDraw
draw = ImageDraw.Draw(frame)
# Cercles/ovales
draw.ellipse([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
# Étoiles, triangles, tout polygone
points = [(x1, y1), (x2, y2), (x3, y3), ...]
draw.polygon(points, fill=(r, g, b), outline=(r, g, b), width=3)
# Lignes
draw.line([(x1, y1), (x2, y2)], fill=(r, g, b), width=5)
# Rectangles
draw.rectangle([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
À ne pas utiliser : Les polices emoji (peu fiables selon les plateformes) ou supposer que des graphiques pré-packagés existent dans cette skill.
Faire des graphiques qui ont de l'allure
Les graphiques doivent avoir une apparence soignée et créative, pas basique. Voici comment :
Utiliser des lignes plus épaisses - Toujours définir width=2 ou plus pour les contours et lignes. Les lignes fines (width=1) ont un air haché et peu professionnel.
Ajouter de la profondeur visuelle :
- Utiliser des dégradés pour les fonds (
create_gradient_background) - Superposer plusieurs formes pour plus de complexité (par exemple, une étoile avec une plus petite étoile dedans)
Rendre les formes plus intéressantes :
- Ne pas simplement dessiner un cercle banal - ajouter des reflets, des anneaux ou des motifs
- Les étoiles peuvent avoir des lueurs (dessiner des versions plus grandes et semi-transparentes derrière)
- Combiner plusieurs formes (étoiles + étincelles, cercles + anneaux)
Faire attention aux couleurs :
- Utiliser des couleurs vibrantes et complémentaires
- Ajouter du contraste (contours sombres sur formes claires, contours clairs sur formes sombres)
- Considérer la composition générale
Pour les formes complexes (cœurs, flocons, etc.) :
- Utiliser des combinaisons de polygones et ellipses
- Calculer les points avec soin pour la symétrie
- Ajouter des détails (un cœur peut avoir une courbe de reflet, les flocons ont des branches complexes)
Soyez créatif et détaillé ! Un bon GIF Slack devrait avoir une apparence soignée, pas ressembler à des graphiques d'espace réservé.
Utilitaires disponibles
GIFBuilder (core.gif_builder)
Assemble les frames et optimise pour Slack :
builder = GIFBuilder(width=128, height=128, fps=10)
builder.add_frame(frame) # Ajouter une Image PIL
builder.add_frames(frames) # Ajouter une liste de frames
builder.save('out.gif', num_colors=48, optimize_for_emoji=True, remove_duplicates=True)
Validators (core.validators)
Vérifier si le GIF respecte les exigences Slack :
from core.validators import validate_gif, is_slack_ready
# Validation détaillée
passes, info = validate_gif('my.gif', is_emoji=True, verbose=True)
# Vérification rapide
if is_slack_ready('my.gif'):
print("Prêt !")
Easing Functions (core.easing)
Mouvement lisse au lieu de linéaire :
from core.easing import interpolate
# Progression de 0.0 à 1.0
t = i / (num_frames - 1)
# Appliquer l'easing
y = interpolate(start=0, end=400, t=t, easing='ease_out')
# Disponible : linear, ease_in, ease_out, ease_in_out,
# bounce_out, elastic_out, back_out
Frame Helpers (core.frame_composer)
Fonctions pratiques pour les besoins courants :
from core.frame_composer import (
create_blank_frame, # Fond de couleur unie
create_gradient_background, # Dégradé vertical
draw_circle, # Helper pour cercles
draw_text, # Rendu texte simple
draw_star # Étoile à 5 branches
)
Concepts d'animation
Shake/Vibrate
Décaler la position d'un objet avec oscillation :
- Utiliser
math.sin()oumath.cos()avec l'index du frame - Ajouter de petites variations aléatoires pour un effet naturel
- Appliquer à la position x et/ou y
Pulse/Heartbeat
Mettre à l'échelle la taille d'un objet de façon rythmée :
- Utiliser
math.sin(t * frequency * 2 * math.pi)pour un pulse lisse - Pour un battement : deux pulsations rapides puis pause (ajuster l'onde sinusoïdale)
- Mettre à l'échelle entre 0,8 et 1,2 de la taille de base
Bounce
Un objet tombe et rebondit :
- Utiliser
interpolate()aveceasing='bounce_out'pour l'atterrissage - Utiliser
easing='ease_in'pour la chute (accélération) - Appliquer la gravité en augmentant la vélocité y à chaque frame
Spin/Rotate
Faire tourner un objet autour du centre :
- PIL :
image.rotate(angle, resample=Image.BICUBIC) - Pour un vacillement : utiliser une onde sinusoïdale pour l'angle au lieu d'une linéaire
Fade In/Out
Apparaître ou disparaître graduellement :
- Créer une image RGBA, ajuster le canal alpha
- Ou utiliser
Image.blend(image1, image2, alpha) - Fade in : alpha de 0 à 1
- Fade out : alpha de 1 à 0
Slide
Déplacer un objet hors de l'écran vers une position :
- Position de départ : hors des limites du frame
- Position de fin : emplacement cible
- Utiliser
interpolate()aveceasing='ease_out'pour un arrêt lisse - Pour un dépassement : utiliser
easing='back_out'
Zoom
Mettre à l'échelle et positionner pour un effet de zoom :
- Zoom in : mettre à l'échelle de 0,1 à 2,0, rogner le centre
- Zoom out : mettre à l'échelle de 2,0 à 1,0
- Peut ajouter un flou de mouvement pour l'effet dramatique (filtre PIL)
Explode/Particle Burst
Créer des particules rayonnant vers l'extérieur :
- Générer des particules avec des angles et vélocités aléatoires
- Mettre à jour chaque particule :
x += vx,y += vy - Ajouter la gravité :
vy += gravity_constant - Atténuer les particules au fil du temps (réduire l'alpha)
Stratégies d'optimisation
Uniquement quand demandé de réduire la taille du fichier, implémenter quelques-unes des méthodes suivantes :
- Moins de frames - FPS inférieur (10 au lieu de 20) ou durée plus courte
- Moins de couleurs -
num_colors=48au lieu de 128 - Dimensions plus petites - 128x128 au lieu de 480x480
- Supprimer les doublons -
remove_duplicates=Truedans save() - Mode emoji -
optimize_for_emoji=Trueoptimise automatiquement
# Optimisation maximale pour emoji
builder.save(
'emoji.gif',
num_colors=48,
optimize_for_emoji=True,
remove_duplicates=True
)
Philosophie
Cette skill fournit :
- Connaissance : Les exigences Slack et les concepts d'animation
- Utilitaires : GIFBuilder, validators, easing functions
- Flexibilité : Créer la logique d'animation avec les primitives PIL
Elle NE fournit PAS :
- Des templates d'animation rigides ou des fonctions pré-construites
- Le rendu de polices emoji (peu fiable selon les plateformes)
- Une bibliothèque de graphiques pré-packagés intégrée à la skill
Note sur les uploads utilisateur : Cette skill n'inclut pas de graphiques pré-construits, mais si un utilisateur upload une image, utiliser PIL pour la charger et y travailler - interpréter en fonction de sa demande s'il veut l'utiliser directement ou juste comme inspiration.
Soyez créatif ! Combiner les concepts (rebond + rotation, pulse + glissement, etc.) et utiliser toutes les capacités de PIL.
Dépendances
pip install pillow imageio numpy