| name | video-to-gif |
| description | Convert video clips to optimized GIFs with speed control, cropping, text overlays, and file size optimization. Create perfect GIFs for social media, documentation, and presentations. |
Video to GIF Workshop
Transform video clips into high-quality, optimized GIFs perfect for social media, documentation, tutorials, and presentations. Features precise timing control, text overlays, effects, and intelligent file size optimization.
Core Capabilities
- Clip Selection: Extract specific time ranges from videos
- Speed Control: Slow motion, speed up, or reverse
- Cropping: Resize and crop to any dimensions
- Text Overlays: Add captions, titles, or watermarks
- Effects: Filters, fades, color adjustments
- Optimization: Smart compression for target file size
- Batch Processing: Convert multiple clips at once
Quick Start
from scripts.gif_workshop import GifWorkshop
workshop = GifWorkshop("video.mp4")
workshop.to_gif("output.gif")
workshop = GifWorkshop("video.mp4")
workshop.clip(start=5, end=10)
workshop.resize(width=480)
workshop.set_fps(15)
workshop.optimize(max_size_kb=500)
workshop.to_gif("output.gif")
Core Workflow
1. Load Video
from scripts.gif_workshop import GifWorkshop
workshop = GifWorkshop("video.mp4")
workshop = GifWorkshop("video.mp4", fps=15, width=480)
2. Select Clip Range
workshop.clip(start=5, end=15)
workshop.clip(start="00:01:30", end="00:01:45")
workshop.clip(start=10)
workshop.clip(end=5)
workshop.clip_multi([
(0, 3),
(10, 15),
(20, 25)
])
3. Adjust Speed
workshop.speed(2.0)
workshop.speed(0.5)
workshop.reverse()
workshop.boomerang()
4. Resize and Crop
workshop.resize(width=480)
workshop.resize(height=360)
workshop.resize(width=480, height=360)
workshop.crop(x=100, y=50, width=400, height=300)
workshop.crop_to_aspect(16, 9)
workshop.crop_to_aspect(1, 1)
5. Add Text
workshop.add_text(
"Hello World!",
position='bottom',
fontsize=24,
color='white'
)
workshop.add_text(
"Watch this!",
position='top',
start_time=0,
end_time=3
)
workshop.add_text("Step 1", position='top-left', start_time=0, end_time=2)
workshop.add_text("Step 2", position='top-left', start_time=2, end_time=4)
workshop.add_caption_bar(
"This is a caption",
position='bottom',
background='black',
padding=10
)
6. Apply Effects
workshop.filter('grayscale')
workshop.filter('sepia')
workshop.adjust(brightness=0.1, contrast=0.2)
workshop.fade_in(duration=0.5)
workshop.fade_out(duration=0.5)
workshop.blur(intensity=2)
7. Optimize for Size
workshop.optimize(max_size_kb=500)
workshop.optimize(
quality='medium',
colors=128
)
workshop.set_fps(10)
workshop.optimize(lossy=80)
8. Export
workshop.to_gif("output.gif")
workshop.to_gif(
"output.gif",
optimize=True,
colors=256,
loop=0
)
workshop.to_video("output.mp4")
workshop.export_frames("frames/", format='png')
Presets
workshop.preset('twitter')
workshop.preset('discord')
workshop.preset('slack')
workshop.preset('reddit')
workshop.preset('high')
workshop.preset('medium')
workshop.preset('low')
workshop.preset('thumbnail')
workshop.preset('reaction')
Text Position Options
| Position | Description |
|---|
'top' | Top center |
'bottom' | Bottom center |
'center' | Center of frame |
'top-left' | Top left corner |
'top-right' | Top right corner |
'bottom-left' | Bottom left corner |
'bottom-right' | Bottom right corner |
Advanced Features
Frame Extraction
best_frame = workshop.get_best_frame()
best_frame.save("thumbnail.png")
frame = workshop.get_frame_at(5.5)
frame.save("frame.png")
workshop.export_frames("frames/", format='png')
Video Information
info = workshop.get_info()
print(f"Duration: {info['duration']} seconds")
print(f"Size: {info['width']}x{info['height']}")
print(f"FPS: {info['fps']}")
print(f"Frames: {info['frame_count']}")
Custom Filters
def custom_filter(frame):
return frame.rotate(5)
workshop.apply_filter(custom_filter)
Concatenate Videos
workshop.concat([
"intro.mp4",
"main.mp4",
"outro.mp4"
])
CLI Usage
python gif_workshop.py video.mp4 -o output.gif
python gif_workshop.py video.mp4 -o output.gif --start 5 --end 15
python gif_workshop.py video.mp4 -o output.gif \
--width 480 \
--fps 15 \
--speed 1.5 \
--max-size 500
python gif_workshop.py video.mp4 -o output.gif \
--text "Hello World" \
--text-position bottom
python gif_workshop.py video.mp4 -o output.gif --preset twitter
Optimization Tips
File Size Reduction
- Reduce dimensions: Smaller = much smaller file
- Lower FPS: 10-15 FPS is usually sufficient
- Limit colors: 64-128 colors often looks fine
- Shorter duration: Each second adds significant size
- Use lossy compression: Small quality loss, big size reduction
Quality Improvement
- Start with high-quality source: Better input = better output
- Use 256 colors: Maximum palette
- Higher FPS: 24-30 FPS for smooth motion
- Avoid heavy compression: Keep lossy above 90
Size vs Quality Presets
| Preset | Width | FPS | Colors | Use Case |
|---|
reaction | 256px | 10 | 64 | Quick reactions |
low | 320px | 12 | 128 | Basic sharing |
medium | 480px | 15 | 256 | General use |
high | 640px | 20 | 256 | High quality |
max | Original | 24 | 256 | Best quality |
Error Handling
from scripts.gif_workshop import GifWorkshop, GifError
try:
workshop = GifWorkshop("video.mp4")
workshop.clip(start=0, end=100)
workshop.to_gif("output.gif")
except GifError as e:
print(f"Error: {e}")
except FileNotFoundError:
print("Video file not found")
Supported Formats
Input (Video)
- MP4, MOV, AVI, MKV, WebM, FLV, WMV
Output
- GIF (animated)
- MP4 (for comparison)
- PNG/JPEG (frames)
Dependencies
moviepy>=1.0.3
Pillow>=10.0.0
imageio>=2.31.0
numpy>=1.24.0
Limitations
- Maximum practical GIF size: ~20-30MB
- Very long GIFs become unwieldy
- Complex scenes may have color banding
- No audio support in GIF format