slack-gif-creator
npx skills add https://github.com/lingxling/awesome-skills-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)
ä¸è¦ä½¿ç¨ï¼ 表æ 符å·åä½ï¼è·¨å¹³å°ä¸å¯é ï¼æåè®¾æ¤æè½ä¸åå¨é¢æå çå¾å½¢ã
使å¾å½¢çèµ·æ¥ç¾è§
å¾å½¢åºè¯¥çèµ·æ¥ç²¾è´åæåæï¼è䏿¯åºç¡ãæ¹æ³å¦ä¸ï¼
ä½¿ç¨æ´ç²ççº¿æ¡ – å§ç»ä¸ºè½®å»å线æ¡è®¾ç½®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å¾å
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 # 5è§æ
)
å¨ç»æ¦å¿µ
ææ/æ¯å¨
ç¨æ¯è¡å移对象ä½ç½®ï¼
- 使ç¨å¸§ç´¢å¼ç
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å¾å å建å¨ç»é»è¾
å®ä¸æä¾ï¼
- åµåçå¨ç»æ¨¡æ¿æé¢å¶ç彿°
- 表æ 符å·å使¸²æï¼è·¨å¹³å°ä¸å¯é ï¼
- å ç½®äºæè½ä¸ç颿å å¾å½¢åº
å ³äºç¨æ·ä¸ä¼ ç说æï¼æ¤æè½ä¸å æ¬é¢æå»ºçå¾å½¢ï¼ä½å¦æç¨æ·ä¸ä¼ å¾åï¼ä½¿ç¨PILå è½½åå¤çå® – æ ¹æ®ä»ä»¬ç请æ±è§£éä»ä»¬æ¯æ³è¦ç´æ¥ä½¿ç¨è¿æ¯ä» ä½ä¸ºçµæã
è¦æåæï¼ç»åæ¦å¿µï¼å¼¹è·³ + æè½¬ï¼èå² + æ»å¨çï¼å¹¶ä½¿ç¨PILçå ¨é¨åè½ã
ä¾èµé¡¹
pip install pillow imageio numpy