slack-gif-creator
Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack."
1How It Works & Mechanism
SKILL.md focuses primarily on "Knowledge + Orchestration": it hardcodes Slack specification constraints into the prompt, guides the agent to hand-draw animations frame-by-frame using PIL primitives, and then delegates them to bundled Python tools for encoding and optimization.
# Slack GIF Creator A toolkit providing utilities and knowledge for creating animated GIFs optimized for Slack. ## Slack Requirements **Dimensions:** - Emoji GIFs: 128x128 (recommended) - Message GIFs: 480x480
Drawing capabilities are entirely delegated to the running Python + Pillow environment: SKILL.md explicitly requires the agent to write PIL drawing code on the fly, and the skill provides no pre-made graphics.
## Philosophy This skill provides: - **Knowledge**: Slack's requirements and animation concepts - **Utilities**: GIFBuilder, validators, easing functions - **Flexibility**: Create the animation logic using PIL primitives It does NOT provide: - Rigid animation templates or pre-made functions - Emoji font rendering (unreliable across platforms) - A library of pre-packaged graphics built into the skill
GIFBuilder is the true core engine: it takes PIL/numpy frame sequences, performs palette quantization, deduplication, automatic emoji-mode scaling/frame dropping, and finally writes to disk using imageio.
def save( self, output_path: str | Path, num_colors: int = 128, optimize_for_emoji: bool = False, remove_duplicates: bool = False, ) -> dict: ... # Optimize colors with global palette optimized_frames = self.optimize_colors(num_colors, use_global_palette=True) # Calculate frame duration in milliseconds frame_duration = 1000 / self.fps # Save GIF imageio.imwrite( output_path, optimized_frames, duration=frame_duration, loop=0, # Infinite loop )
validators reads back generated GIFs using PIL for independent quality checks, forming a closed "generation → self-check" loop.
def validate_gif( gif_path: str | Path, is_emoji: bool = True, verbose: bool = True ) -> tuple[bool, dict]: """ Validate GIF for Slack (dimensions, size, frame count). ... with Image.open(gif_path) as img: width, height = img.size # Count frames frame_count = 0 try: while True: img.seek(frame_count) frame_count += 1 except EOFError: pass
Animation concepts (shake/pulse/bounce/spin/fade/slide/zoom/explode) are injected purely via SKILL.md text descriptions, implemented on the fly by the agent using easing utility functions + math.
### Bounce Object falls and bounces: - Use `interpolate()` with `easing='bounce_out'` for landing - Use `easing='ease_in'` for falling (accelerating) - Apply gravity by increasing y velocity each frame
2Core Capabilities
3External Dependencies
| Kind | Dependency / Endpoint |
|---|---|
| package | pillow (PIL) |
| package | imageio(v3 API,GIF 写盘) |
| package | imageio-ffmpeg |
| package | numpy(帧为 np.ndarray、相似度/像素堆叠计算) |
4Recommended Governance & Evidence
- scripts/: Execute local scripts or commands: The host-side skill usage is "agent generates Python code on the fly based on SKILL.md and executes it" (SKILL.md is full of API examples, no __m
- 本地工作目录: File read/write and artifact output: GIFBuilder.save() writes GIF files according to the output_path parameter (path is provided by agent-generated code and can be any path)
5Second-Pass Verification
- [ok] 外部依赖 pillow — requirements 声明 pillow>=10.0.0;gif_builder.py/frame_composer.py/validators.py 均真实 `import`/`from PIL import`,调用点充分
- [ok] 外部依赖 imageio(GIF 编码) — requirements 声明 imageio>=2.31.0;gif_builder.py:12 `import imageio.v3 as imageio`,save() 中 imageio.imwrite 真实调用
- [discrepancy] 外部依赖 imageio-ffmpeg — requirements.txt:3 声明 imageio-ffmpeg>=0.4.9,但 4 个核心 py 文件均无直接 import;imageio 写 GIF 走自有/ Pillow 后端,不必然需要 ffmpeg。属冗余或为 imageio 其他格式兜底,仅作防御性声明。影响:安装清单略夸大
- [ok] 外部依赖 numpy — gif_builder.py/frame_composer.py 真实 import numpy;帧去重(np.abs/mean)、调色板采样(np.vstack)确有调用
- [ok] 无网络调用/凭据读取/隐藏执行 — 第二遍全目录正则复查零命中;无隐藏文件、无子模块、无 __main__/argparse;easing.py 仅 import math
- [discrepancy] 『Slack Requirements』与 validators 门槛一致性 — SKILL.md 头部写 Emoji 128x128 / Message 480x480、FPS 10-30、Colors 48-128;validators.py 实际门槛为 emoji 64-128 方形通过、message 仅查宽高比≤2 且短边 320-640——与『480x480』宣称不符;且均未给出 Slack 官方文档出处,属启发式规格。另 builder.save() 默认 num_colors=128 超出文档推荐的 48-128 上限(128 是上限本身,相符);emoji 优化强制 48 色却把帧数砍到 ~12(fps 名义不变,时长被压缩),与头部『FPS 10-30』经验值存在偏差
- [ok] SKILL.md 功能声明 vs 代码能力相符性 — 声明的 GIFBuilder/validators/easing/frame_composer 四模块全部真实存在且 API 签名与文档一致;create_gradient_background、draw_star 等均实现;draw_text 用 load_default() 位图字体与『不用 emoji 字体』哲学一致;『remove_duplicates=True』去重阈值 0.9995 与 docstring 相符
- [ok] 帧/尺寸写入行为 — add_frame 会把非目标尺寸帧 LANCZOS 重采样到 builder 尺寸;save 返回 size_kb/size_mb/dimensions/frame_count/fps/duration_seconds/colors 信息字典并打印 ✓ 摘要——与文档一致
6Verdict & Scenarios
9d54ca459d0b781f…