Web-based tool for turning green-screen character videos into mobile-ready sprite sheets, with AI background removal and frame-by-frame touch-up in the browser.
Upload an MP4, let the matting model cut out the background, clean up the stray pixels by hand with a canvas eraser, and export a packed sprite sheet plus a metadata JSON that any game or animation runtime can consume.
Green-screen source on the left, transparent result on the right. The checkerboard is alpha.
- Python 3.10+
- ffmpeg on your
PATH(used for frame extraction)
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # optional for local dev
python manage.py runserver
# Open http://127.0.0.1:8000The first run downloads the selected matting model into ~/.u2net/, which is
anywhere from 100 MB to 900 MB depending on which one you pick. Later runs
reuse the cache.
examples/ has two complete jobs, each with the green-screen
source video plus the sprite sheet and metadata the tool produced from it.
Both are 40 frames at 10fps.
| Source video | Result | Sprite sheet |
|---|---|---|
![]() |
![]() |
![]() Celebrating, 2842×4092, 7×6 grid mp4 · png · json |
![]() |
![]() |
![]() Concerned, 2016×3954, 7×6 grid mp4 · png · json |
Upload a .mp4 to exercise the full pipeline, or import a finished .png plus
.json pair to jump straight into the editor without waiting on the model.
- Upload a green-screen video (MP4).
- The matting model removes the background and the despill pass neutralises green light bleeding onto the subject's edges.
- Edit frame by frame with the canvas eraser, or re-run the AI on a single bad frame with a different model.
- Export a sprite sheet plus metadata JSON.
You can also import an existing sprite sheet (PNG plus metadata JSON) to split it back into editable frames.
- Eight AI matting models (U²-Net, ISNet, BiRefNet, BEN2) selectable per job
- Optional temporal matting backend (Robust Video Matting) for flicker-free edges on moving subjects
- Luminance-preserving, alpha-gated green despill that leaves sub-pixel edge geometry (hair, fingers, motion blur) intact
- Canvas eraser with variable brush size, per-frame undo
- Filmstrip navigation and animation playback preview
- Export to a GPU-safe sprite sheet (max 4096×4096)
- Keyboard shortcuts.
←/→navigate,Eerase,Ctrl+Zundo,Ctrl+Ssave
The rvm backend uses Robust Video Matting,
a recurrent network that carries state across frames and largely eliminates
edge boiling. It needs PyTorch.
pip install -r requirements-rvm.txtAll settings are read from the environment. See .env.example.
| Variable | Default | Purpose |
|---|---|---|
DJANGO_SECRET_KEY |
none | Required when DJANGO_DEBUG=0 |
DJANGO_DEBUG |
1 |
Debug pages, and serves /media/ from the dev server |
DJANGO_ALLOWED_HOSTS |
none | Comma-separated hosts, used when debug is off |
MAX_UPLOAD_MB |
200 |
Upload size ceiling |
This is a single-user local tool, not a multi-tenant service. There is no
authentication, and anyone who can reach the server can upload videos, run GPU
work, and read every session's frames by guessing a session id. Run it on
127.0.0.1, or put it behind your own auth layer and a real WSGI server before
exposing it. With DJANGO_DEBUG=0 you must also serve media/ yourself,
because Django's dev-server media route is disabled outside debug.
Uploaded videos, frames, and exports accumulate under media/sessions/ and are
never garbage-collected, so prune that directory yourself.
mascot-studio/
├── manage.py
├── requirements.txt
├── mascot_studio/ # Django settings
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── editor/ # Django app
│ ├── views.py # Pages + API endpoints
│ ├── urls.py
│ └── templates/editor/
│ ├── upload.html # Video upload + processing page
│ └── edit.html # Canvas frame editor
├── processor/ # Processing pipeline
│ └── pipeline.py # Frame extraction, matting, despill, stitching
└── media/ # Uploads, frames, exports (created at runtime)
| Method | Path | Description |
|---|---|---|
GET |
/ |
Upload page |
GET |
/edit/<session>/ |
Frame editor |
POST |
/api/upload/ |
Upload video, trigger processing |
GET |
/api/models/ |
List matting models and cache status |
POST |
/api/import/ |
Import a sprite sheet back into frames |
POST |
/api/save-frame/<session>/ |
Save an edited frame |
POST |
/api/reprocess-frame/<session>/ |
Re-run AI on one frame |
POST |
/api/export/<session>/ |
Generate sprite sheet |
Export produces sprite.png and sprite.json.
{
"frameWidth": 320, "frameHeight": 480,
"totalFrames": 24, "fps": 10, "duration": 2.4,
"columns": 5, "rows": 5,
"sheetWidth": 1600, "sheetHeight": 2400
}Frames are packed left-to-right, top-to-bottom, so frame i sits at
(i % columns * frameWidth, i // columns * frameHeight).
I build the mobile side of projects like this one. If you want to hire iOS developers for your app, book a free meeting from my site and we can talk through the scope and what it would cost.
MIT, see LICENSE.





