Skip to content
Video & Audio
Skill

/claude-gif-edit

Edit and modify existing GIFs. Speed change, reverse, ping-pong, crop, resize, text overlay, frame extraction, loop control, trim. Uses gifsicle for frame-level operations and FFmpeg for filters. Use when user says "edit gif", "gif speed", "reverse gif", "crop gif", "resize

BOOST
From plugin
claude-gif
296 skills
Install
$ npx -y skills add AgriciDaniel/claude-gif --skill claude-gif-edit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/claude-gif-edit

Context preview

The summary Claude sees to decide when to auto-load this skill.

Edit and modify existing GIFs. Speed change, reverse, ping-pong, crop, resize, text overlay, frame extraction, loop control, trim. Uses gifsicle for frame-level operations and FFmpeg for filters. Use when user says "edit gif", "gif speed", "reverse gif", "crop gif", "resize

SKILL.md

claude-gif-edit.SKILL.md
name: claude-gif-edit
description: >
  Edit and modify existing GIFs. Speed change, reverse, ping-pong, crop, resize,
  text overlay, frame extraction, loop control, trim. Uses gifsicle for frame-level
  operations and FFmpeg for filters. Use when user says "edit gif", "gif speed",
  "reverse gif", "crop gif", "resize gif", "add text to gif", "gif text overlay",
  "extract frames", "loop gif", "ping pong gif", or "trim gif".
allowed-tools:
  - Bash
  - Read

claude-gif-edit -- GIF Editing and Modification

Modifies existing GIFs using gifsicle for frame-level operations and FFmpeg for filters and complex transformations. All edits preserve the original file (output to a new path).

Pre-Flight

Before ANY edit:

bash ~/.claude/skills/claude-gif/scripts/preflight.sh INPUT.gif OUTPUT.gif

Analyze Before Editing

Always inspect the GIF first:

# Quick stats
gifsicle --info INPUT.gif

# Detailed: dimensions, frame count, duration
ffprobe -v error -show_entries stream=width,height,nb_frames,r_frame_rate \
  -show_entries format=duration -of json INPUT.gif

# File size
stat -c%s INPUT.gif

---

Edit Operations

1. Speed Change

**Speed up** (shorter delay between frames):

# 2x speed: halve the delay
gifsicle --delay 3 INPUT.gif -O3 -o OUTPUT.gif

# General formula: --delay is in centiseconds (1/100th of a second)
# 10fps = --delay 10, 15fps = --delay 7, 20fps = --delay 5, 30fps = --delay 3

**Slow down**:

# 0.5x speed: double the delay
gifsicle --delay 13 INPUT.gif -O3 -o OUTPUT.gif

**Precise speed change via FFmpeg** (re-encodes, so also apply palette):

# 2x speed
ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] setpts=0.5*PTS,fps=15,scale=480:-1:flags=lanczos,split [a][b]; \
   [a] palettegen=stats_mode=diff [p]; \
   [b][p] paletteuse=dither=floyd_steinberg:diff_mode=rectangle" \
  -loop 0 OUTPUT.gif

# 0.5x speed
ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] setpts=2.0*PTS,fps=15,scale=480:-1:flags=lanczos,split [a][b]; \
   [a] palettegen=stats_mode=diff [p]; \
   [b][p] paletteuse=dither=floyd_steinberg:diff_mode=rectangle" \
  -loop 0 OUTPUT.gif

Speed multiplier to PTS factor: `PTS_factor = 1.0 / speed_multiplier`

  • 2x speed: `setpts=0.5*PTS`
  • 3x speed: `setpts=0.333*PTS`
  • 0.5x speed: `setpts=2.0*PTS`

2. Reverse

# Simple reverse via FFmpeg (re-encodes with palette)
ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] reverse,fps=15,scale=480:-1:flags=lanczos,split [a][b]; \
   [a] palettegen [p]; \
   [b][p] paletteuse=dither=floyd_steinberg" \
  -loop 0 OUTPUT.gif

**Frame-level reverse via gifsicle** (preserves quality, no re-encode):

# Get frame count
FRAMES=$(gifsicle --info INPUT.gif | grep -oP '\d+ images' | grep -oP '\d+')
# Reverse frame order
gifsicle INPUT.gif $(seq $((FRAMES-1)) -1 0 | sed 's/^/#/') -O3 -o OUTPUT.gif

3. Ping-Pong (Boomerang)

Play forward then backward for a seamless bounce effect:

~/.video-skill/bin/python3 ~/.claude/skills/claude-gif/scripts/gif_loop.py \
  --input INPUT.gif \
  --method pingpong \
  --output OUTPUT.gif

**Manual via gifsicle**:

FRAMES=$(gifsicle --info INPUT.gif | grep -oP '\d+ images' | grep -oP '\d+')
FORWARD=$(seq 0 $((FRAMES-1)) | sed 's/^/#/')
REVERSE=$(seq $((FRAMES-2)) -1 1 | sed 's/^/#/')
gifsicle INPUT.gif $FORWARD $REVERSE -O3 --loop -o OUTPUT.gif

4. Crop

# Crop to region: --crop X,Y+WxH (from top-left corner)
gifsicle --crop 50,20+300x200 INPUT.gif -O3 -o OUTPUT.gif

# Center crop to square
W=$(gifsicle --info INPUT.gif | grep -oP 'logical screen \K\d+')
H=$(gifsicle --info INPUT.gif | grep -oP 'logical screen \d+x\K\d+')
SIZE=$((W < H ? W : H))
X=$(( (W - SIZE) / 2 ))
Y=$(( (H - SIZE) / 2 ))
gifsicle --crop ${X},${Y}+${SIZE}x${SIZE} INPUT.gif -O3 -o OUTPUT.gif

**FFmpeg crop** (with re-palette):

ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] crop=300:200:50:20,split [a][b]; \
   [a] palettegen [p]; \
   [b][p] paletteuse" \
  -loop 0 OUTPUT.gif

5. Resize

# Resize with gifsicle (fast, no re-palette)
gifsicle --resize-width 320 INPUT.gif -O3 -o OUTPUT.gif
gifsicle --resize-height 240 INPUT.gif -O3 -o OUTPUT.gif
gifsicle --resize 320x240 INPUT.gif -O3 -o OUTPUT.gif  # Exact (may distort)
gifsicle --resize-fit 320x240 INPUT.gif -O3 -o OUTPUT.gif  # Fit within (aspect preserved)

# Resize with FFmpeg (re-palettes for better quality)
bash ~/.claude/skills/claude-gif/scripts/gif_convert.sh \
  --input INPUT.gif \
  --width 320 \
  --output OUTPUT.gif

6. Text Overlay

Add text to a GIF using FFmpeg drawtext filter:

ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] fps=15,scale=480:-1:flags=lanczos, \
   drawtext=text='Hello World':fontsize=36:fontcolor=white:borderw=2:bordercolor=black: \
   x=(w-text_w)/2:y=h-text_h-20,split [a][b]; \
   [a] palettegen [p]; \
   [b][p] paletteuse=dither=floyd_steinberg" \
  -loop 0 OUTPUT.gif

**Meme-style top and bottom text**:

ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] fps=15,scale=480:-1:flags=lanczos, \
   drawtext=text='TOP TEXT':fontsize=40:fontcolor=white:borderw=3:bordercolor=black: \
   x=(w-text_w)/2:y=20:font='Impact', \
   drawtext=text='BOTTOM TEXT':fontsize=40:fontcolor=white:borderw=3:bordercolor=black: \
   x=(w-text_w)/2:y=h-text_h-20:font='Impact',split [a][b]; \
   [a] palettegen [p]; \
   [b][p] paletteuse=dither=floyd_steinberg" \
  -loop 0 OUTPUT.gif

**Animated text** (fade in):

# Text fades in over first 30 frames
ffmpeg -n -i INPUT.gif -filter_complex \
  "[0:v] fps=15,scale=480:-1:flags=lanczos, \
   drawtext=text='Appearing Text':fontsize=36:fontcolor=white@%{eif\\:min(1\\,n/30)\\:d}: \
   borderw=2:bordercolor=black:x=(w-text_w)/2:y=(h-text_h)/2,split [a][b]; \
   [a] palettegen [p]; \
   [b][p] paletteuse" \
  -loop 0 OUTPUT.gif

7. Frame Extraction

**Extract all frames**:

mkdir -p /tmp/claude-gif/extracted_frames
gifsic
Read more
Ships withclaude-gif

GIF creation skill for Claude Code with 6 generation pipelines: AI video-to-GIF (Veo 3.1), programmatic animations (Remotion), AI image sequences (Gemini/FLUX.2), animated SVG-to-transparent-GIF (Playwright), video conversion (FFmpeg), and GIF

Get the whole plugin

Other skills on claude-gif.