QUICKUPSCALE

PRACTICAL GUIDE

Pixel-art PNGs and transparency

Batch resize PNG assets with the Aseprite CLI

Start here

Run one --batch INPUT --scale 2 --save-as OUTPUT command per selected PNG, sequentially, into a new output directory. The tested loop preserved filenames, including spaces and Unicode, and left the source PNG hashes unchanged.

Expected result:

Three named 2× PNG exports match integer replication for visible RGBA and alpha. RGB beneath alpha zero changes, so keep the originals when hidden color values matter.

What you need

Use the original MIT-licensed inputs and scripts in the download. It contains three PNGs with transparent edges and a partially transparent pixel, batch.sh, reference metadata and licenses. It contains no Aseprite executable.

You need Bash 4+ and an already working, verified Aseprite runtime. The results below use a local GPLv2 Aseprite 1.1.7-dev build from commit 000ac2e. Current desktop versions and GUI menu operations were not executed.

Tested with: Local GPLv2 Aseprite 1.1.7-dev, source commit 000ac2e8949a0400a0b0604b2da4647040f732f3; Linux ARM64 container with Xvfb; independent Pillow 12.3.0 decoding.

1. Use an already working native CLI

The recorded executable was /runtime/aseprite, with its data directory and an Xvfb display available inside the container. Its version command returned:

Aseprite 1.1.7-dev

Extract the package and read its environment notes. Record the input hashes before processing, using the PNG entries in assets/fixture-manifest.json as the original-file reference. Keep the output directory separate from the inputs.

2. Select files explicitly and run the loop

The recorded run mounted inputs at /work/assets, scripts at /work/scripts and results at /work/runs. These are the exact environment setting and batch invocation:

export ASEPRITE_BIN=/runtime/aseprite
bash /work/scripts/batch.sh /work/runs/t02-good \
  '/work/assets/batch/walk idle.png' \
  '/work/assets/batch/雪 sprite.png' \
  /work/assets/batch/torch.png

In the extracted ZIP, batch.sh is at the package root: substitute ./batch.sh and your own absolute input/output paths for the recorded mounts. Set ASEPRITE_BIN to your verified executable. Keep the quoted arguments and their order; the script starts one native process at a time.

For the first input, the inner native command resolves to:

/runtime/aseprite --batch '/work/assets/batch/walk idle.png' \
  --scale 2 --save-as '/work/runs/t02-good/walk idle.png'

The input, scale and save option order follows this build’s pinned CLI definitions. The package-relative paths are substitutions for your environment, not a separately recorded execution.

3. Inspect the report and actual exports

The recorded outcomes.tsv contained three ok rows in selection order. summary.txt reported successes=3 and failures=0. Output basenames were unchanged, and the original PNG byte hashes still matched their references.

Original inputs and actual two-times native output dimensions
Original inputInput sizeActual 2× output
walk idle.png12×924×18
雪 sprite.png7×514×10
torch.png5×810×16
Actual two-times Aseprite CLI export of walk idle.png
walk idle.png: 24×18px. Actual CLI export; not a GUI capture.
Actual two-times Aseprite CLI export of 雪 sprite.png
雪 sprite.png: 14×10px. Actual CLI export; not a GUI capture.
Actual two-times Aseprite CLI export of torch.png
torch.png: 10×16px. Actual CLI export; not a GUI capture.

4. Distinguish visible pixels from hidden RGB

Independent Pillow decoding compared every output pixel with 2× nearest-neighbor replication of its input. All alpha values and all RGBA values at nonzero alpha matched. Fully transparent output pixels had changed RGB at 152, 80 and 88 positions for walk idle.png, 雪 sprite.png and torch.png, respectively.

This is a visible-pixel/alpha result, not full decoded-RGBA identity. For your own inputs, verify dimensions, compare the pixels you need to preserve and repeat the source-hash check after processing. A successful report alone does not decode or validate PNG contents.

5. Reject false success and inspect partial results

The deliberate assets/failures/invalid.png input exposed a real failure: this old Aseprite printed PNG/load errors, returned exit 0, and created no PNG. The wrapper requires both process success and a fresh nonempty output; it reports that selection as native-export-failed.

In the executed valid/invalid/unreadable selection, the wrapper exited 2, retained the first valid output and reported both failures separately. It does not roll back successful selections. A duplicate basename is rejected after the first output; an existing destination is refused with exit 64 before processing.

Use a new destination for every run so an old PNG cannot masquerade as a new export. Inspect the outcome rows and native logs before using partial results. These small fixtures do not establish current-version compatibility or large-file performance.

Sources and next steps