slack-gif-creator
npx skills add https://github.com/leastbit/claude_skills_zh-cn --skill slack-gif-creator
Agent 安装分布
Skill 文档
Slack GIF å建å¨
ä¸ä¸ªæä¾å·¥å ·åç¥è¯çå·¥å ·å ï¼ç¨äºå建é对 Slack ä¼åçå¨ç» GIFã
Slack è¦æ±
尺寸ï¼
- 表æ ç¬¦å· GIFï¼128×128ï¼æ¨èï¼
- æ¶æ¯ GIFï¼480×480
åæ°ï¼
- FPSï¼10-30ï¼è¾ä½çå¼å¯å尿件大å°ï¼
- é¢è²ï¼48-128ï¼é¢è²è¶å° = æä»¶è¶å°ï¼
- æ¶é¿ï¼è¡¨æ ç¬¦å· GIF åºæ§å¶å¨ 3 ç§ä»¥å
æ ¸å¿å·¥ä½æµç¨
from core.gif_builder import GIFBuilder
from PIL import Image, ImageDraw
# 1. å建æå»ºå¨
builder = GIFBuilder(width=128, height=128, fps=10)
# 2. çæå¸§
for i in range(12):
frame = Image.new('RGB', (128, 128), (240, 248, 255))
draw = ImageDraw.Draw(frame)
# ä½¿ç¨ PIL åºç¡å¾å½¢ç»å¶ä½ çå¨ç»
# ï¼åå½¢ãå¤è¾¹å½¢ã线æ¡çï¼
builder.add_frame(frame)
# 3. ä¿åå¹¶ä¼å
builder.save('output.gif', num_colors=48, optimize_for_emoji=True)
ç»å¶å¾å½¢
å¤çç¨æ·ä¸ä¼ çå¾ç
å¦æç¨æ·ä¸ä¼ äºå¾çï¼è¯·èèä»ä»¬æ³è¦ï¼
- ç´æ¥ä½¿ç¨ï¼ä¾å¦ï¼”ç»è¿ä¸ªæ·»å å¨ç»”ï¼”æè¿ä¸ªåæå¸§”ï¼
- ä½ä¸ºçµæåèï¼ä¾å¦ï¼”å¶ä½ç±»ä¼¼è¿æ ·çä¸è¥¿”ï¼
ä½¿ç¨ PIL å è½½åå¤çå¾çï¼
from PIL import Image
uploaded = Image.open('file.png')
# ç´æ¥ä½¿ç¨ï¼æä»
ä½ä¸ºé¢è²/飿 ¼çåè
ä»é¶å¼å§ç»å¶
ä»é¶å¼å§ç»å¶å¾å½¢æ¶ï¼ä½¿ç¨ PIL ImageDraw åºç¡å¾å½¢ï¼
from PIL import ImageDraw
draw = ImageDraw.Draw(frame)
# åå½¢/æ¤å
draw.ellipse([x1, y1, x2, y2], fill=(r, g, b), outline=(r, g, b), width=3)
# æå½¢ãä¸è§å½¢ãä»»ä½å¤è¾¹å½¢
points = [(x1, y1), (x2, y2), (x3, y3), ...]
draw.polygon(points, fill=(r, g, b), outline=(r, g, b), width=3)
# 线æ¡
draw.line([(x1, y1), (x2, y2)], fill=(r, g, b), width=5)
# ç©å½¢
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) # æ·»å PIL Image
builder.add_frames(frames) # æ·»å 帧å表
builder.save('out.gif', num_colors=48, optimize_for_emoji=True, remove_duplicates=True)
éªè¯å¨ (core.validators)
æ£æ¥ GIF æ¯å¦ç¬¦å Slack è¦æ±ï¼
from core.validators import validate_gif, is_slack_ready
# 详ç»éªè¯
passes, info = validate_gif('my.gif', is_emoji=True, verbose=True)
# å¿«éæ£æ¥
if is_slack_ready('my.gif'):
print("åå¤å°±ç»ªï¼")
ç¼å¨å½æ° (core.easing)
å¹³æ»è¿å¨èé线æ§ï¼
from core.easing import interpolate
# è¿åº¦ä» 0.0 å° 1.0
t = i / (num_frames - 1)
# åºç¨ç¼å¨
y = interpolate(start=0, end=400, t=t, easing='ease_out')
# å¯ç¨ï¼linear, ease_in, ease_out, ease_in_out,
# bounce_out, elastic_out, back_out
帧è¾
å©å½æ° (core.frame_composer)
常ç¨éæ±ç便æ·å½æ°ï¼
from core.frame_composer import (
create_blank_frame, # 纯è²èæ¯
create_gradient_background, # åç´æ¸å
draw_circle, # åå½¢è¾
å©å½æ°
draw_text, # ç®åæå渲æ
draw_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 - åå°å°ºå¯¸ – 128×128 è䏿¯ 480×480
- ç§»é¤éå¤å¸§ – å¨ save() ä¸ä½¿ç¨
remove_duplicates=True - 表æ
ç¬¦å·æ¨¡å¼ –
optimize_for_emoji=Trueèªå¨ä¼å
# 表æ
ç¬¦å·æå¤§ä¼å
builder.save(
'emoji.gif',
num_colors=48,
optimize_for_emoji=True,
remove_duplicates=True
)
设计ç念
æ¬æè½æä¾ï¼
- ç¥è¯ï¼Slack çè¦æ±åå¨ç»æ¦å¿µ
- å·¥å ·ï¼GIFBuilderãéªè¯å¨ãç¼å¨å½æ°
- çµæ´»æ§ï¼ä½¿ç¨ PIL åºç¡å¾å½¢å建å¨ç»é»è¾
æ¬æè½ä¸æä¾ï¼
- åµåçå¨ç»æ¨¡æ¿æé¢å¶å½æ°
- Emoji å使¸²æï¼å¨ä¸åå¹³å°ä¸è¡¨ç°ä¸ä¸è´ï¼
- å ç½®äºæè½ä¸ç颿å å¾å½¢åº
å ³äºç¨æ·ä¸ä¼ ç说æï¼æ¬æè½ä¸å å«é¢æå»ºçå¾å½¢ï¼ä½å¦æç¨æ·ä¸ä¼ äºå¾çï¼è¯·ä½¿ç¨ PIL å è½½åå¤çå® – æ ¹æ®ä»ä»¬ç请æ±å¤ææ¯ç´æ¥ä½¿ç¨è¿æ¯ä» ä½ä¸ºçµæåèã
忥åæï¼ç»ååç§æ¦å¿µï¼å¼¹è·³ + æè½¬ãèå¨ + æ»å¨çï¼å¹¶å åå©ç¨ PIL çå ¨é¨åè½ã
ä¾èµé¡¹
pip install pillow imageio numpy