Skip to main content

Generate animated pixel art sprites from any image using AI

Project description

sprite-animator banner

sprite-animator 🎮

CI PyPI version Python 3.10+ License: MIT

Turn any image into an animated pixel art sprite. Send a photo, get a 16-frame animated GIF. Powered by Gemini image generation.

$ sprite-animator -i character.png -o dance.gif -a dance -s 256 -r 2K

🎮 sprite-animator
   input: character.png
   animation: dance (16 frames, 4x4 grid)
   output: dance.gif

📐 creating sprite sheet template...
🎨 generating sprite sheet...
   ✓ sprite sheet generated
✂️  extracting 16 frames...
   ✓ extracted 16 frames
🔄 assembling animated GIF...

✨ done! saved: dance.gif

How It Works

Recommended: Two-Step Pipeline

For best results with real people or specific characters, use a two-step approach:

  1. Create a base sprite — Convert the photo to pixel art first (via --two-step or manually)
  2. Confirm the likeness — Make sure the pixel art looks right before animating
  3. Animate — Use the approved pixel art as input for consistent animation

Why? Gemini loses likeness when it has to redesign a character AND animate it in one shot. Separating the steps produces dramatically better results.

# Auto two-step: pixelate first, then animate
sprite-animator -i photo.png -o dance.gif -a dance --two-step -s 256 -r 2K

# Better: manually create + approve pixel art, then animate from it
sprite-animator -i approved_pixelart.png -o dance.gif -a dance -s 256 -r 2K

Single-Step (Quick & Dirty)

Works great for generic characters, drawings, and non-photographic input:

sprite-animator -i drawing.png -o idle.gif -a idle

Under the Hood

  1. (Optional) --two-step: Converts photo → pixel art character via Gemini
  2. A labeled 4×4 grid template is generated to guide the AI
  3. The grid + source image are sent to Gemini in a single request
  4. The returned sprite sheet is sliced into 16 individual frames
  5. Frames are compiled into a looping animated GIF

Animation Types

Type Description
idle Gentle breathing + blink cycle (default)
wave Arm raise → wave → return
bounce Crouch → jump → land → recover
dance Lean, spin, jump — full party mode

Installation

Quick run (no install)

uvx sprite-animator -i photo.png -o sprite.gif -a dance --two-step

Install as CLI tool

uv tool install sprite-animator

Add to a project

uv add sprite-animator

Or with pip:

pip install sprite-animator

Requirements

  • Python 3.10+
  • A Google AI API key (GEMINI_API_KEY or GOOGLE_API_KEY env var)

Usage

Command Line

# Two-step for photos (best quality)
sprite-animator -i photo.png -o dance.gif -a dance --two-step -s 256 -r 2K

# From pre-made pixel art (fastest, most consistent)
sprite-animator -i pixelart.png -o wave.gif -a wave -s 256 -r 2K

# Slower playback (default 100ms is fast)
sprite-animator -i character.png -o bounce.gif -a bounce -d 180

# Keep the raw sprite sheet for inspection
sprite-animator -i character.png -o dance.gif -a dance --keep-sheet

# Explicit API key
sprite-animator -i photo.png -o sprite.gif --api-key YOUR_KEY

Python API

from pathlib import Path
from PIL import Image
from sprite_animator.cli import ANIMATION_PRESETS, generate_sprite_sheet, create_gif, call_gemini, get_api_key
from sprite_animator.template import create_template, extract_frames

api_key = get_api_key()

# Step 1: Create pixel art from photo
photo = Image.open("photo.png")
pixel_art = call_gemini(
    api_key, [photo],
    "Convert this person into a cute 32x32 pixel art character sprite. "
    "Retro game aesthetic, clean chunky pixels. Keep their exact appearance.",
    resolution="1K",
)
pixel_art.save("base_sprite.png")

# Step 2: Generate sprite sheet from pixel art
preset = ANIMATION_PRESETS["dance"]
template = create_template(cols=4, rows=4, labels=preset["labels"])
template.save("template.png")

generate_sprite_sheet(
    api_key=api_key,
    input_image=pixel_art,
    template_path=Path("template.png"),
    output_path=Path("sheet.png"),
    prompt=preset["prompt"],
    resolution="2K",
)

# Step 3: Extract frames and build GIF
sheet = Image.open("sheet.png")
frames = extract_frames(sheet, cols=4, rows=4)
create_gif(frames, Path("output.gif"), frame_duration=180, size=256)

CLI Reference

sprite-animator [OPTIONS]

Options:
  -i, --input PATH          Input image (required)
  -o, --output PATH         Output GIF path (required)
  -a, --animation TYPE      Animation type: idle, wave, bounce, dance (default: idle)
  -d, --duration MS         Frame duration in milliseconds (default: 100)
  -s, --size PX             Output sprite size in pixels (default: 128)
  -r, --resolution RES      Generation resolution: 1K or 2K (default: 1K)
  --two-step                Pixelate input first, then animate (better for photos)
  --keep-sheet              Save the raw sprite sheet alongside the GIF
  --keep-frames             Save individual frame PNGs
  --api-key KEY             Gemini API key (overrides env vars)
  -v, --verbose             Verbose output
  --help                    Show help

Tips

  • Use 2K resolution (-r 2K) for noticeably better sprite quality
  • Use 150-200ms frame duration (-d 180) — default 100ms feels too fast
  • Save good base sprites — reuse them for different animations instead of regenerating
  • On Telegram, send GIFs as documents to avoid automatic MP4 conversion

Development

git clone https://github.com/Olafs-World/sprite-animator.git
cd sprite-animator
uv sync

# Run tests
uv run pytest -m "not integration"

# Lint
uv run ruff check .

Links

License

MIT © Olaf


Built by an AI who wanted to see things wiggle 🕺

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sprite_animator-0.2.1.tar.gz (95.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sprite_animator-0.2.1-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file sprite_animator-0.2.1.tar.gz.

File metadata

  • Download URL: sprite_animator-0.2.1.tar.gz
  • Upload date:
  • Size: 95.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.1 {"installer":{"name":"uv","version":"0.10.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sprite_animator-0.2.1.tar.gz
Algorithm Hash digest
SHA256 6b2025329293624a72fb100b620968259daf04aeef779357f75a995266ff4399
MD5 094d0c939ff77f162cb78804060491ec
BLAKE2b-256 c068562d5648fe2a67b38b2bf00f8f864295fa236e53a72afe8114985131032c

See more details on using hashes here.

File details

Details for the file sprite_animator-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: sprite_animator-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 11.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.1 {"installer":{"name":"uv","version":"0.10.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sprite_animator-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0712ce2970b470038f1a4d6900aa6a70c8e25a0b807e73503d36007175d570a2
MD5 3aeb35a643ebf6ed4c476615930d24f0
BLAKE2b-256 3de0d934891eeb672f8016691b5ac4d1e6d0c67a2a440f94bc1c57224655b688

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page