Skip to content

Sprite Compiler Usage Guide

Complete guide to using the PixelRoot32 Sprite Compiler for converting images to sprite data.

Basic Usage

Launching the GUI

The easiest way to use the compiler is via the Graphical User Interface (GUI).

python main.py

This will open the application where you can interactively load images, configure the grid, and export sprites.

Command Line Interface (CLI)

For automation, you can use the CLI mode by passing arguments to the script.

python main.py [input] [options]

Required:

  • input: Input PNG image file
  • --grid WxH: Grid cell size (e.g., 16x16)
  • --sprite gx,gy,gw,gh: Sprite definition (can be repeated)

Optional:

  • --prefix NAME: Prefix for generated arrays (e.g., PLAYER_JUM)
  • --out FILE: Output header file (default: sprites.h)
  • --offset X,Y: Initial offset in pixels (default: 0,0)
  • --mode MODE: Export mode (layered, 2bpp, 4bpp)

CLI Examples

Simple Conversion

Convert a single 16x16 sprite located at the top-left corner:

python main.py player.png --grid 16x16 --sprite 0,0,1,1 --out player.h

Multiple Sprites

Convert multiple sprites from a single sheet:

python main.py sheet.png --grid 16x16 \
  --sprite 0,0,1,1 \
  --sprite 1,0,1,1 \
  --sprite 2,0,1,1 \
  --out animations.h

Export Modes

Layered (Default): Generates multiple uint16_t arrays, one for each color layer. Best for standard PixelRoot32 rendering.

python main.py icon.png --grid 16x16 --sprite 0,0,1,1 --mode layered

Packed 2bpp: Generates a single array with 2 bits per pixel (4 colors max).

python main.py icon.png --grid 16x16 --sprite 0,0,1,1 --mode 2bpp

Step-by-Step Examples

Example 1: Simple Player Sprite

Step 1: Create Image

  • Create an 8x8 pixel PNG image
  • Use black and white colors
  • Save as player.png

Step 2: Compile

python main.py player.png --grid 8x8 --sprite 0,0,1,1 --prefix PLAYER --out player_sprite.h

Step 3: Use in Code

#include "player_sprite.h"

void draw() {
    // PLAYER_SPRITE_0_LAYER_0 is generated automatically
    renderer.drawSprite(PLAYER_SPRITE_0_LAYER_0, 100, 100, Color::White);
}

Example 2: Multiple Animation Frames

Step 1: Prepare Images

  • Create frames: walk_0.png, walk_1.png, walk_2.png
  • All same size (e.g., 16x16)

Step 2: Batch Compile

pr32-sprite-compiler --batch walk_*.png --output-dir animations/ --prefix WALK_

Step 3: Use in Animation

#include "animations/walk_0.h"
#include "animations/walk_1.h"
#include "animations/walk_2.h"

const Sprite* WALK_FRAMES[] = {
    &WALK_0_SPRITE,
    &WALK_1_SPRITE,
    &WALK_2_SPRITE
};

Example 3: Sprite Sheet

Step 1: Create Sprite Sheet

  • Create a 64x64 image with 4x4 grid of 16x16 sprites
  • Save as characters.png

Step 2: Split Sheet

pr32-sprite-compiler characters.png characters.h --sheet 16x16 --count 16

Step 3: Use Individual Sprites

#include "characters.h"

// Sprites named CHARACTER_0, CHARACTER_1, etc.
renderer.drawSprite(CHARACTER_0, 50, 50, Color::White);
renderer.drawSprite(CHARACTER_1, 70, 50, Color::White);

Batch Processing

Process Multiple Files

Process all PNG files in a directory:

pr32-sprite-compiler --batch sprites/*.png --output-dir generated/

With Options

Apply options to all files:

pr32-sprite-compiler --batch assets/*.png \
    --output-dir src/sprites/ \
    --format 1bpp \
    --prefix SPRITE_

Recursive Processing

Process subdirectories:

pr32-sprite-compiler --batch assets/**/*.png --output-dir generated/

Sprite Sheets

Automatic Splitting

Split a sprite sheet into individual sprites:

pr32-sprite-compiler sheet.png output.h --sheet 8x8 --count 16

Parameters:

  • --sheet WxH: Tile size (width x height)
  • --count N: Number of sprites in sheet

Grid Layout

Specify grid dimensions:

pr32-sprite-compiler sheet.png output.h \
    --sheet 16x16 \
    --grid 4x4 \
    --count 16

Parameters:

  • --grid WxH: Grid dimensions (columns x rows)

Custom Naming

Name sprites with index:

pr32-sprite-compiler sheet.png output.h \
    --sheet 8x8 \
    --count 8 \
    --prefix CHARACTER_ \
    --indexed

Generates: CHARACTER_0, CHARACTER_1, etc.

Custom Palettes

Using Palette File

Convert with custom color palette:

pr32-sprite-compiler sprite.png output.h --palette palette.json

Palette JSON format:

{
  "colors": [
    {"r": 0, "g": 0, "b": 0, "name": "black"},
    {"r": 255, "g": 255, "b": 255, "name": "white"}
  ]
}

Built-in Palettes

Use predefined palettes:

pr32-sprite-compiler sprite.png output.h --palette nes
pr32-sprite-compiler sprite.png output.h --palette gb
pr32-sprite-compiler sprite.png output.h --palette pico8

Advanced Options

Threshold for Grayscale

Set threshold for black/white conversion:

pr32-sprite-compiler sprite.png output.h --threshold 128

Values: 0-255 (default: 127)

Dithering

Enable dithering for better gradients:

pr32-sprite-compiler sprite.png output.h --dither

Alignment

Control output alignment:

pr32-sprite-compiler sprite.png output.h --align 4

Endianness

Specify byte order:

pr32-sprite-compiler sprite.png output.h --endian little
pr32-sprite-compiler sprite.png output.h --endian big

Output Customization

Namespace

Wrap output in namespace:

pr32-sprite-compiler sprite.png output.h --namespace MyGame

Header Guard

Custom header guard:

pr32-sprite-compiler sprite.png output.h --guard MY_SPRITE_H

Include Paths

Custom include paths:

pr32-sprite-compiler sprite.png output.h \
    --include "<graphics/Sprite.h>" \
    --include "<stdint.h>"

Integration with Build Systems

PlatformIO

Add to platformio.ini:

[env:esp32dev]
extra_scripts = 
    pre:scripts/compile_sprites.py

compile_sprites.py:

Import("env")
import subprocess

subprocess.run([
    "pr32-sprite-compiler",
    "--batch", "assets/sprites/*.png",
    "--output-dir", "src/sprites/"
])

Makefile

SPRITES = $(wildcard assets/sprites/*.png)
SPRITE_HEADERS = $(SPRITES:assets/sprites/%.png=src/sprites/%.h)

src/sprites/%.h: assets/sprites/%.png
 pr32-sprite-compiler $< $@ --name $(shell basename $< .png | tr '[:lower:]' '[:upper:]')_SPRITE

sprites: $(SPRITE_HEADERS)

CMake

file(GLOB SPRITE_FILES "assets/sprites/*.png")

foreach(SPRITE ${SPRITE_FILES})
    get_filename_component(SPRITE_NAME ${SPRITE} NAME_WE)
    add_custom_command(
        OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/sprites/${SPRITE_NAME}.h
        COMMAND pr32-sprite-compiler
        ARGS ${SPRITE} ${CMAKE_CURRENT_SOURCE_DIR}/src/sprites/${SPRITE_NAME}.h
        DEPENDS ${SPRITE}
    )
endforeach()

GUI Usage (If Available)

Opening GUI

pr32-sprite-compiler --gui

Or launch the GUI application directly.

GUI Workflow

  1. Drag and drop images into the window
  2. Preview sprite data in real-time
  3. Adjust settings visually (format, threshold, etc.)
  4. Export to header files
  5. Batch process multiple files

GUI Features

  • Visual preview of sprite conversion
  • Real-time threshold adjustment
  • Palette selection
  • Batch processing interface
  • Export options

Best Practices

Image Preparation

  • Use indexed color PNG for best results
  • Keep sprites small (8x8, 16x16, 32x32)
  • Use black and white for 1bpp
  • Limit colors for 2bpp/4bpp formats

File Organization

project/
├── assets/
│   └── sprites/
│       ├── player.png
│       ├── enemy.png
│       └── items.png
├── src/
│   └── sprites/          # Generated headers
│       ├── player.h
│       ├── enemy.h
│       └── items.h
└── platformio.ini

Naming Conventions

  • Use descriptive names: player_walk_0.pngPLAYER_WALK_0_SPRITE
  • Be consistent: All caps for sprite names
  • Use prefixes: ENEMY_, PLAYER_, ITEM_

Version Control

  • Commit generated headers (they're part of the build)
  • Or add to .gitignore and regenerate on build
  • Keep source images in version control

Troubleshooting

Common Issues

"Image too large":

  • Sprites must be ≤ 16 pixels wide for 1bpp
  • Resize image or split into multiple sprites

"Colors not converting correctly":

  • Use indexed color PNG
  • For 1bpp: Use only black and white
  • For 2bpp: Use exactly 4 colors
  • For 4bpp: Use up to 16 colors

"Output file not found":

  • Check write permissions
  • Verify output directory exists
  • Use absolute paths if needed

"Invalid format":

  • Ensure input is PNG format
  • Check file is not corrupted
  • Try re-saving image in image editor

Getting Help

pr32-sprite-compiler --help

Shows all available options and usage.

Next Steps

See Also