Converts noisy pixel-art-style images into crisp clean pixel-resolution sprites.
On Windows:
.\target\release\fixpix.exe .\input.pngConvert one image with defaults:
fixpix ./tests/sources/dragon_coffee_2.pngLimit the color palette to a max of 8 colors:
fixpix ./tests/sources/dragon_coffee_2.png --colors 8Write debug artifacts:
fixpix ./tests/sources/dragon_coffee_2.png \
--output ./art/dragon.png \
--debug-out ./art/dragon-debug.png \
--unscaled-out ./art/dragon-unscaled.png \
--palette-out ./art/dragon-palette.png \
--palette-scale 8Downscale a high-resolution image into a 32x32 sprite:
fixpix ./tests/sources/armor2.png ./art/armor2.png \
--downscale 32x32 \
--colors auto \
--scale 16Batch convert a directory using eight CPU workers:
fixpix ./tests/sources ./art/restored --jobs 8Convert an image from a URL:
fixpix "https://example.com/sprites/pixel_art.png" --output ./sprite.pngUse Hough-only pixel-width detection:
fixpix ./input.png --pixel-width-detector houghPrint transform metadata as JSON:
fixpix ./input.png --metadataForce a known source pixel width:
fixpix ./input.png --pixel-width 8| Option | Type | Default | Description |
|---|---|---|---|
<input-path-or-url> |
path or URL | required unless --input is used |
Input image path, input directory, or http:// / https:// URL. |
[output-path-or-dir] |
path | derived automatically | Optional positional output file or directory. |
-i, --input <value> |
path or URL | none | Alternative to positional input. Do not use both forms at the same time. |
-o, --output <path> |
path | derived automatically | Output file path or output directory. |
-j, --jobs <n> |
positive integer | available CPU count | CPU worker count for batch work and the global Rayon pool. |
--threads <n> |
positive integer | available CPU count | Alias for --jobs. |
-c, --colors <integer|auto|full> |
integer, auto, or full |
auto |
Palette mode. Use auto or 0 to iteratively choose a palette size for the selected clustering mode, a positive integer to force that many colors, or full / any negative integer to skip color clustering. |
--palette-merge-threshold <n> |
number | 1 |
Color-only merge threshold used by regular palette selection. 0 keeps more exact color distinctions. |
--color-sample-grid-size <n> |
positive integer | 5 |
Cell sampling control. 1 samples only the center; values above 1 use dominant cell color sampling. |
--palette-strategy <global|sampled> |
enum | global |
global builds the palette from image-wide color stats. sampled builds it from sampled cell colors. |
--palette-clustering <regular|spatial> |
enum | regular |
regular uses color-only clustering. spatial clusters with color and image position so similar distant regions can stay separate. |
-s, --scale <n> |
positive integer | automatic | Final integer output scale. Overrides automatic scale selection. |
--auto-scale-width <n> |
positive integer | none | Target width for automatic output scaling. Must be used with --auto-scale-height. |
--auto-scale-height <n> |
positive integer | none | Target height for automatic output scaling. Must be used with --auto-scale-width. |
--downscale <n|WxH> |
positive integer or size | none | Fits the source into the requested size before pixel processing. With --transparent, first removes detected boundary background and crops transparent padding. A single number means square size. |
--downscale-sample-from <pixelated|original> |
enum | pixelated |
pixelated keeps the resized downscale result. original samples dominant colors from the cleaned original image. |
-t, --transparent |
flag | false |
Masks detected boundary-connected background before sampling and removes adjacent sampled background fringes. |
--edge-close-kernel-size <n> |
0 or odd integer |
3 |
Closes the detected edge mask before using it as a transparency flood-fill barrier and in debug edge previews. 0 disables closing. |
--crop |
flag | false |
Crops transparent padding from the final unscaled sprite. |
--crop-size <n|WxH> |
positive integer or size | none | Crops transparent padding and centers content in the requested canvas size. A single number means square size. |
-w, --pixel-width <n> |
positive integer | automatic detection | Forces a known source pixel width. |
--pixel-width-detector <projection|hough|hybrid> |
enum | hybrid |
Selects automatic pixel-width detection strategy. |
-u, --initial-upscale <n> |
positive integer | 2 |
Upscale factor used before mesh detection. Higher values can help small inputs but cost more CPU time. |
--min-input-width <n> |
integer | 512 |
Minimum input width used for pixel processing. If the source is smaller, it is doubled with nearest-neighbor scaling until this width is met. 0 disables the width check. |
--min-input-height <n> |
integer | 512 |
Minimum input height used for pixel processing. If the source is smaller, it is doubled with nearest-neighbor scaling until this height is met. 0 disables the height check. |
--warp-subdivision-depth <n> |
integer 0-4 |
2 |
Maximum adaptive warp subdivision depth. 0 disables subdivision; higher values allow bent pixel boundaries to be followed where local edge evidence justifies splitting. |
--warp-subdivision-edge-threshold <n> |
number | 18 |
Minimum local edge strength required before an internal warp subdivision point can move. Higher values ignore weaker texture/artifact edges. |
-f, --format <png|jpeg|webp> |
enum | inferred or png |
Output format. If omitted, inferred from output path, URL extension, or defaults to PNG. |
-q, --quality <1-100> |
integer | encoder default | JPEG quality. PNG ignores this option. WebP quality is currently rejected because WebP output uses the lossless encoder. |
--url-timeout-ms <n> |
positive integer | 30000 |
Timeout for URL input downloads, in milliseconds. |
--url-max-bytes <n> |
positive integer | 52428800 |
Maximum URL input size in bytes. Checked against Content-Length when available and while reading the response. |
--url-content-types <list> |
comma-separated MIME list | image/*,application/octet-stream |
Allowed URL response content types. Exact types and wildcards such as image/* are supported. |
--debug-out <path> |
path | none | Writes a combined debug sheet with source preview, edge preview, line overlays, grid overlay, final image, palette, and palette cluster graph when clustering runs. Transparent-background runs put background mask and sampled mask coverage panels on their own row. |
--debug-scale <n> |
positive integer | 6 |
Scale used for debug sheet previews. |
--unscaled-out <path> |
path | none | Writes the unscaled cleaned sprite before final output scaling. |
--palette-out <path> |
path | none | Writes a palette swatch image. |
--palette-scale <n> |
positive integer | 6 |
Scale used for the palette swatch artifact. |
--metadata |
flag | false |
Prints transform metadata as JSON to stdout instead of output paths. |
-h, --help |
flag | false |
Prints command help. |
projection: Fast projection/autocorrelation detector. Good for clear regular grids.hough: Hough-style line detector with anchor-line mesh reconstruction. Useful for text-heavy or line-rich pixel art.hybrid: Default. Uses projection and Hough evidence together, with fallbacks for noisy inputs.
- PNG: default output.
- JPEG: supported, with optional
--quality. - WebP: supported with lossless encoding.
--qualityis rejected for WebP until a self-contained lossy WebP encoder is selected.
By default, the CLI uses the available CPU count. Use either --jobs or
--threads to set a fixed global CPU budget:
fixpix ./input-dir ./output-dir --jobs 16The same thread pool is used for batch work and per-image CPU work.
cargo build --release --bin fixpixRun formatting, linting, and tests:
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo testcargo test also regenerates the default visual inspection outputs under
output/, including the spatial clustering comparison in
output/spatial-clustering/.
Run the benchmark smoke test:
cargo run --release --bin fixpix-benchGenerate visual artifacts manually:
cargo run --release --bin generate-visual-artifacts -- default,transparencyWith no category argument, the generator reads defaults from
tests/visual-artifacts-manifest.json. Useful environment filters:
VISUALS_CATEGORIES=detector,palette \
VISUALS_FIXTURES=fish,tiles \
VISUALS_MAX_PROCESSES=8 \
cargo run --release --bin generate-visual-artifactsOn PowerShell:
$env:VISUALS_CATEGORIES="detector,palette"
$env:VISUALS_FIXTURES="fish,tiles"
$env:VISUALS_MAX_PROCESSES="8"
cargo run --release --bin generate-visual-artifactsFixPix is licensed under the GNU General Public License v3.0 only. See
LICENSE for the full license text.
AI tools where used in the process of creating this project.
