A tool for easily creating expression difference images for PNGTubers.
📝 Usage Guide (Japanese, note.com)
- Added auto-trimming for alignment borders.
When saving frommask_composer.py,parts_mixer.py, orsimple_aligner_app.py, blank edges introduced by alignment can be removed automatically. - In each save section, enable "Auto-trim alignment borders" and adjust margin (px) if needed.
- To minimize remaining border area, set margin to
0px.
- Select eyes and mouth from different sources, auto-generate 4 patterns
- Split & align from 2x2 expression sheets
- High-precision alignment using AKAZE / ORB feature matching
- Auto-trim blank borders created by alignment when saving
- Visualized alignment status (scores and success ratios)
- Re-tuning flow for low-score images (threshold and quick jump)
- Auto-saved tool settings (last directories and key UI options)
- Overlay display for comparing differences while drawing masks
- Japanese file path support
- Simple GUI (PySide6)
First, you need to prepare an expression sheet (a 2x2 image with expression variations) — see Step 2.
# Download or clone the repository
git clone https://github.com/rotejin/EasyPNGTuber.git
cd EasyPNGTuber
# Install dependencies (virtual environment created automatically)
uv syncIf uv is not installed:
pip install uvor see official site
-
Prepare a character image
- Get a single image of the character you want to make into a PNGTuber
-
Create a 2x2 image with Grid Tiler
uv run python grid_tiler.py
- Drag & drop your image
- Click "Save Tiled Image" to export the 2x2 image
-
Generate expressions with AI
- Use Google AI Studio's image generation AI (Nano Banana)
- Upload the 2x2 image and generate expression variations with this prompt:
Show prompt (click to expand)
expression_sheet: task: "edit_reference_image" format: grid: "2x2" preserve: "exact_pixel_position" critical_rule: source: "use provided reference image as base" maintain: - original_art_style - original_character_design - original_face_angle - original_head_tilt - original_color_palette - original_lighting - original_line_weight do_not_change: - head_position - face_outline - hair - background - overall_composition editable_elements: - eyelids_only - mouth_only parts_definition: eyes: open: "natural relaxed open state" closed: "gentle blink, relaxed eyelids" mouth: closed: "lips together, neutral" open: "natural speaking, showing inside" panels: top_left: action: "keep_unchanged" top_right: eyes: "open" mouth: "open" bottom_left: eyes: "closed" mouth: "closed" bottom_right: eyes: "closed" mouth: "open"
uv run python parts_mixer.pyLoad the generated expression sheet into Parts Mixer, combine eye and mouth parts, and export 4 patterns for your PNGTuber.
Select eye and mouth parts from different source images and auto-generate 4 patterns (eyes ON/OFF × mouth ON/OFF).
Useful when AI-generated expression sheets have some parts that didn't turn out as expected.
uv run python parts_mixer.py- Drag & drop an expression sheet
- Click "Split & Align"
- Select Base image / Eye source / Mouth source (if base has closed eyes & mouth, select open eyes for eye source, open mouth for mouth source)
- Draw eye region mask on Eye canvas
- Draw mouth region mask on Mouth canvas
- 4 patterns appear in preview
- Click "Save 4 Patterns" to export
{original_name}_eyeOFF_mouthOFF.png- Eyes OFF, Mouth OFF{original_name}_eyeON_mouthOFF.png- Eyes ON, Mouth OFF{original_name}_eyeOFF_mouthON.png- Eyes OFF, Mouth ON{original_name}_eyeON_mouthON.png- Eyes ON, Mouth ON
The sample/ folder contains sample images for testing.
tomari_sample.png- Sample 2x2 expression sheet
- Verify Python 3.10+ is installed
- Delete
.venvfolder and re-runuv sync
- Supported formats: PNG, JPG, BMP, WebP
- Japanese file names are supported
- May fail if image differences are too large
- Rotations beyond ±30 degrees are not supported
- Enable "Auto-trim alignment borders" when saving
- Use margin (px) to keep a small safety border if needed
- AKAZE feature matching (primary)
- ORB (fallback)
- RANSAC for affine transformation estimation
- Binary descriptors are matched with binary-appropriate distance metrics
- A valid-region mask is generated together with each affine transform
- Save-time cropping uses the intersection of valid regions across selected images
- One shared crop rectangle is applied to all outputs to keep frame dimensions consistent
| Parameter | Value |
|---|---|
| Max rotation | ±30 degrees |
| Scale range | 0.8x ~ 1.2x |
| Success score threshold | 0.6 or higher |
| Item | Requirement |
|---|---|
| Python | 3.10 or higher |
| OS | Windows / macOS / Linux |
| Package Manager | uv recommended |
EasyPNGTuber/
├── parts_mixer.py # Main tool: Parts composition
├── grid_tiler.py # Image tiling
├── mask_composer.py # Mask composition
├── simple_aligner_app.py # Image alignment
├── aligner.py # Alignment engine
├── compositor.py # Image compositing engine
├── cv2_utils.py # OpenCV utilities
├── mask_canvas.py # Mask canvas UI
├── preview_widget.py # Preview UI
├── gemini_prompt.txt # AI prompt
├── pyproject.toml # Dependency definitions
└── sample/ # Sample images
Copyright (c) 2026 rotejin