关于 creating-slack-gifs
为 Slack GIF 制作提供知识与 Python 工具的技能,适用于需要绘制和优化动画的创作者。它包含 GIF 组装、验证、缓动和帧绘制辅助工具,并强调在实际尺寸下检查可辨识度。
主要功能
- 01GIFBuilder 帧组装与保存
- 02Slack 规格验证
- 03缓动函数与帧辅助工具
- 04PIL 图形绘制指导
- 05缩小尺寸与循环效果检查
适用场景
- 01制作 Slack 表情 GIF
- 02将上传图片制作成动画
- 03验证 GIF 规格及小尺寸可读性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ osmontero/ opencode-skills --skill creating-slack-gifs安装后在 Claude Code 中输入/creating-slack-gifs确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtcore/easing.pyframe_composer.pygif_builder.pyvalidators.py详细介绍
创建 Slack GIF
此技能提供用于创建符合 Slack 特定要求的动画 GIF 的实用工具和知识。
Slack 要求
尺寸:
- 表情 GIF:128x128(推荐)
- 消息 GIF:480x480
参数:
- FPS:10-30(越低,文件越小)
- 颜色:48-128(越少,文件越小)
- 时长:表情 GIF 控制在 3 秒以内
核心工作流
from core.gif_builder import GIFBuilder
from PIL import Image, ImageDraw
# 1. Create builder
builder = GIFBuilder(width=128, height=128, fps=10)
# 2. Generate frames
for i in range(12):
frame = Image.new('RGB', (128, 128), (240, 248, 255))
draw = ImageDraw.Draw(frame)
# Draw your animation using PIL primitives
# (circles, polygons, lines, etc.)
builder.add_frame(frame)
# 3. Save with optimization
builder.save('output.gif', num_colors=48, optimize_for_emoji=True)
绘制图形
使用用户上传的图像
如果用户上传了图像,请考虑他们是想:
- 直接使用(例如,“将其制作成动画”“将其拆分为帧”)
- 以此为灵感(例如,“制作类似这样的内容”)
使用 PIL 加载并处理图像:
from PIL import Image
uploaded = Image.open('file.png')
# Use directly, or just as reference for colors/style
从头开始绘制
从头开始绘制图形时,请使用 PIL ImageDraw 基本图形:
from PIL import ImageDraw
draw = ImageDraw.Draw(frame)
# Circles/ovals
draw.ellipse([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
# Stars, triangles, any polygon
points = [(x1, y1), (x2, y2), (x3, y3), ...]
draw.polygon(points, fill=(r, g, b), outline=(r, g, b), width=3)
# Lines
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)
不要使用: Emoji 字体(跨平台表现不可靠),也不要假设此技能中包含预先打包的图形。
让图形更美观
图形应精致且富有创意,而不是简单粗糙。方法如下:
使用较粗的线条 - 绘制轮廓和线条时,始终设置 width=2 或更高。较细的线条(width=1)看起来会不流畅且显得业余。
增加视觉层次:
- 为背景使用渐变(
create_gradient_background) - 叠加多个形状以增加复杂度(例如,在一颗星星内再画一颗较小的星星)
让形状更有趣:
- 不要只画一个普通圆形——添加高光、环形或图案
- 可以为星星添加光晕(在后面绘制更大、半透明的星星)
- 组合多个形状(星星 + 闪光、圆形 + 圆环)
注意颜色搭配:
- 使用鲜艳、互补的颜色
- 增加对比度(浅色形状配深色轮廓,深色形状配浅色轮廓)
- 考虑整体构图
对于复杂形状(爱心、雪花等):
- 组合使用多边形和椭圆
- 仔细计算点的位置,确保对称
- 添加细节(爱心可以有高光曲线,雪花可以有精巧的分支)
发挥创意,注重细节!优秀的 Slack GIF 应该看起来精致,而不是像占位图形。
可用工具
GIFBuilder(core.gif_builder)
组装帧并针对 Slack 进行优化:
builder = GIFBuilder(width=128, height=128, fps=10)
builder.add_frame(frame) # Add PIL Image
builder.add_frames(frames) # Add list of frames
builder.save('out.gif', num_colors=48, optimize_for_emoji=True, remove_duplicates=True)
Validators(core.validators)
检查 GIF 是否符合 Slack 要求:
from core.validators import validate_gif, is_slack_ready
# Detailed validation
passes, info = validate_gif('my.gif', is_emoji=True, verbose=True)
# Quick check
if is_slack_ready('my.gif'):
print("Ready!")
Easing Functions(core.easing)
让运动更加平滑,而非线性变化:
from core.easing import interpolate
# Progress from 0.0 to 1.0
t = i / (num_frames - 1)
# Apply easing
y = interpolate(start=0, end=400, t=t, easing='ease_out')
# Available: linear, ease_in, ease_out, ease_in_out,
# bounce_out, elastic_out, back_out
Frame Helpers(core.frame_composer)
为常见需求提供便捷函数:
from core.frame_composer import (
create_blank_frame, # Solid color background
create_gradient_background, # Vertical gradient
draw_circle, # Helper for circles
draw_text, # Simple text rendering
draw_star # 5-pointed star
)
动画概念
抖动/振动
通过振荡改变对象位置:
- 使用
math.sin()或math.cos(),并传入帧索引 - 添加少量随机变化,让效果更自然
- 应用于 x 和/或 y 位置
脉动/心跳
有节奏地缩放对象:
- 使用
math.sin(t * frequency * 2 * math.pi)实现平滑脉动 - 心跳效果:快速脉动两次,然后暂停(调整正弦波)
- 在基础尺寸的 0.8 到 1.2 倍之间缩放
弹跳
对象下落并弹起:
- 使用
interpolate(),并设置easing='bounce_out'实现落地效果 - 下落时使用
easing='ease_in'(逐渐加速) - 每帧增加 y 方向速度以模拟重力
旋转
围绕中心旋转对象:
- PIL:
image.rotate(angle, resample=Image.BICUBIC) - 摇摆效果:使用正弦波改变角度,而非线性变化
淡入/淡出
逐渐显现或消失:
- 创建 RGBA 图像并调整 alpha 通道
- 或使用
Image.blend(image1, image2, alpha) - 淡入:alpha 从 0 变为 1
- 淡出:alpha 从 1 变为 0
滑动
将对象从屏幕外移至指定位置:
- 起始位置:画面边界之外
- 结束位置:目标位置
- 使用
interpolate(),并设置easing='ease_out'实现平滑停止 - 要实现过冲效果,请使用
easing='back_out'
缩放
通过缩放和定位实现缩放效果:
- 放大:从 0.1 缩放至 2.0,并裁剪中心部分
- 缩小:从 2.0 缩放至 1.0
- 可添加运动模糊增强戏剧效果(PIL 滤镜)
爆炸/粒子喷发
创建向外辐射的粒子:
- 以随机角度和速度生成粒子
- 更新每个粒子:
x += vx、y += vy - 添加重力:
vy += gravity_constant - 随时间淡出粒子(降低 alpha)
优化策略
仅在用户要求缩小文件体积时,才采用以下几种方法:
- 减少帧数 - 降低 FPS(例如 10 而不是 20)或缩短时长
- 减少颜色 - 使用
num_colors=48而不是 128 - 缩小尺寸 - 使用 128x128 而不是 480x480
- 移除重复帧 - 在 save() 中使用
remove_duplicates=True - 表情符号模式 - 使用
optimize_for_emoji=True自动优化
# Maximum optimization for emoji
builder.save(
'emoji.gif',
num_colors=48,
optimize_for_emoji=True,
remove_duplicates=True
)
理念
此技能提供:
- 知识:Slack 的要求和动画概念
- 实用工具:GIFBuilder、验证器、缓动函数
- 灵活性:使用 PIL 基元创建动画逻辑
此技能不提供:
- 固定的动画模板或预制函数
- 表情符号字体渲染(在不同平台上的表现不可靠)
- 技能内置的预制图形库
关于用户上传内容的说明:此技能不包含预制图形,但如果用户上传了图片,请使用 PIL 加载并处理图片;根据用户的请求判断他们是想直接使用图片,还是仅将其作为灵感。
发挥创意!组合不同概念(弹跳 + 旋转、脉动 + 滑动等),充分运用 PIL 的功能。
验证 — 展示前
Slack 消息中的表情符号显示尺寸大约为 22×22 px。一张 128×128 的设计图即使以原尺寸查看时很清晰,在实际显示尺寸下也可能变成难以辨认的一团;这是最常见的问题。
from PIL import Image
from core.validators import validate_gif
passes, info = validate_gif('out.gif', is_emoji=True, verbose=True)
print(info) # dimensions, frame count, file size, color count
# What Slack actually shows — inspect this, not the 128px version
im = Image.open('out.gif')
im.seek(0); im.convert('RGB').resize((22, 22), Image.LANCZOS).resize(
(176, 176), Image.NEAREST).save('/tmp/emoji-actual-size.png')
读取 /tmp/emoji-actual-size.png,并确认主体仍可辨认。然后检查:
- 在 22px 下仍可辨认。 轮廓要清晰。小于约 4px 的描边细节会完全消失。
- 在两种背景下都清晰。 Slack 有浅色和深色主题——检查 GIF 在
#ffffff和#1a1d21背景上的效果。深色主体在透明背景上会在深色模式中消失。 - 循环流畅。 最后一帧必须自然衔接第一帧。循环图像每次重复时出现明显跳变,是最令人分心的缺陷。
- 表情符号小于 128 KB(Slack 的硬性限制),消息 GIF 小于 2 MB。
- 快速播放时动作仍清晰。 以 10 fps 播放时,12 帧动画时长为 1.2s。如果关键瞬间只占 2 帧,就没人能看清。
- 闪烁频率不超过 3 Hz。 快速闪烁的表情符号会在繁忙频道中造成真实的癫痫风险。
无缝循环检查——对于循环动画,第一帧和最后一帧应当几乎相同:
import numpy as np
frames = []
im = Image.open('out.gif')
for i in range(im.n_frames):
im.seek(i); frames.append(np.asarray(im.convert('RGB'), dtype=float))
delta = np.abs(frames[0] - frames[-1]).mean()
print(f"loop seam delta: {delta:.1f}") # under ~6 is a clean cycle
先决条件
运行任何 Python 脚本前,请激活 opencode 虚拟环境:
source ~/.local/opencode-venv/bin/activate
然后正常使用 python3 core/...。所有依赖项(Pillow、imageio、imageio-ffmpeg、numpy)均由 opencode Python venv 集中管理。
相关技能
- designing-frontend-interfaces —
designing-frontend-interfaces/references/motion.md介绍缓动方式的选择和编排;designing-frontend-interfaces/references/color-and-theme.md介绍如何构建能适应 48 色量化的调色板 - designing-canvas-art —
canvas-fonts/提供 GIF 需要文字时可用的真实字体;designing-canvas-art/references/rendering.md介绍 PIL 合成技巧