A .NET 10 console tool for splitting tall stitched images (PNG or JPEG) into individual pages. Originally built for manga/comic long-strips, but works for any vertically stacked image.
- Auto-detect page seams using a two-signal algorithm (brightness diff + Sobel edge energy)
- Auto-tune threshold for the most evenly-spaced split without manual tuning
- Clean integer cuts — when the detected page count divides the image height evenly, uses exact pixel-perfect cuts with zero remainder
- Chunk mode for images that stitch together multiple series with different page heights
- Split by page count or split by fixed pixel height as manual fallbacks
- Recursive directory processing — batch process entire folder trees in one run
- CBZ output — optionally pack each split result into a
.cbzarchive - EvenSplit / UnevenSplit sorting — automatically route outputs based on page-height uniformity
- Debug signal image — save a visual plot of the seam-detection signal for troubleshooting (auto mode)
- Skip images — run the analysis without writing individual page files
- Delete images after CBZ — automatically clean up split page files once the CBZ is created
- Long path support — works with paths exceeding the Windows 260-character MAX_PATH limit
- Supports PNG and JPEG input/output
- Interactive wizard and CLI flag modes
- .NET 10 SDK
- Windows (uses
System.Drawing/GDI+) - Spectre.Console for colored console output (installed automatically via NuGet)
Run with no arguments to start the wizard:
SplitImages.exe
Choose processing mode:
1. Single file
2. Directory (recursive)
Enter mode (1-2):
Output images are saved to a subfolder next to the input file (single-file mode) or mirrored under the chosen output root (directory mode), e.g. chapter_split/.
Pass options directly for scripting or automation:
SplitImages.exe --input <path> [--output <dir>] [options]
| Option | Short | Default | Description |
|---|---|---|---|
--input |
-i |
(required) | Input image file or directory path |
--output |
-o |
auto-derived | Output directory (required when input is a directory) |
--split-mode |
-m |
auto |
Split mode: auto, count, or height |
--page-count |
Number of pages (--split-mode count) |
||
--page-height |
Page height in pixels (--split-mode height) |
||
--auto-adjust |
false |
Equalize all page heights (--split-mode height) |
|
--threshold |
auto-tune | Peak threshold factor (--split-mode auto) |
|
--cv-good |
0.01 |
Auto-tune CV target | |
--factor-min |
0.5 |
Auto-tune factor range minimum | |
--factor-max |
10.0 |
Auto-tune factor range maximum | |
--factor-step |
0.1 |
Auto-tune factor step size | |
--min-page-height |
800 |
Minimum page height in pixels | |
--chunks |
1 |
Chunk count for mixed-height series | |
--cbz |
false |
Create a CBZ archive for each split result | |
--cbz-name-from-dir |
false |
Name the CBZ after the containing directory | |
--separate-uneven |
false |
Sort into EvenSplit/UnevenSplit subfolders |
|
--cv-threshold |
0.0 |
CV threshold for even/uneven classification | |
--save-debug-signal |
false |
Save seam-detection signal as a debug image (--split-mode auto only) |
|
--skip-images |
false |
Skip saving individual split page images | |
--delete-images-after-cbz |
false |
Delete split images after CBZ is created (requires --cbz) |
Examples:
# Auto-detect, single file
SplitImages.exe --input chapter.png
# Split a directory into CBZ files, 8 pages each
SplitImages.exe --input C:\manga\vol1 --output C:\out --split-mode count --page-count 8 --cbz
# Auto-detect a directory, sort even vs uneven splits
SplitImages.exe --input C:\manga --output C:\out --separate-uneven --cv-threshold 0.05The tool analyzes the image signal and finds page seams automatically.
| Option | Description |
|---|---|
--threshold |
Multiplier on average signal to qualify a peak as a seam. Omit to auto-tune. |
--min-page-height |
Seams closer together than this value are ignored. Default: 800px. |
--chunks |
Split the image into N independent bands, each auto-tuned separately (see below). |
Auto-tune sweeps threshold factors from 0.5 to 10.0 in 0.1 steps and picks the strictest factor that still produces pages with ≤ 1% height variance (coefficient of variation). Falls back to the globally lowest-CV factor if none meet the target.
Chunk mode is useful when a single stitched file contains multiple series or chapters with different page heights. Each band is auto-tuned and clean-divided independently.
Chunk mode for mixed-height series? (y/n, press Enter for n): y
Number of series/chunks (press Enter for 2): 3
Series 1 (Y 0-10000): 7 pages at 1428px (clean divide)
Series 2 (Y 10000-20000): 6 pages at 1666px (clean divide)
Series 3 (Y 20000-30000): 8 pages at 1250px (clean divide)
Detected 19 page seam(s)
Divides the image into an exact number of equal pages. The last page absorbs any remainder pixels if the height is not evenly divisible.
SplitImages.exe --input chapter.png --split-mode count --page-count 8
Splits at a fixed pixel interval. With --auto-adjust, the height is nudged so all pages are exactly equal.
SplitImages.exe --input chapter.png --split-mode height --page-height 1500 --auto-adjust
Adjusted to 1481px per page (12 pages, all equal height)
Add --cbz (CLI) or answer y to the CBZ prompt (wizard) to pack each split folder into a .cbz file alongside it. By default the archive is named after the split folder (e.g. chapter_split.cbz). Use --cbz-name-from-dir to name it after the parent directory instead.
When processing a directory with --separate-uneven, output folders are routed into EvenSplit/ or UnevenSplit/ subtrees based on how uniform the resulting page heights are. The --cv-threshold controls the boundary — 0.0 means every page must be exactly the same height; 0.05 allows up to 5% coefficient of variation.
C:\out\
EvenSplit\vol1\chapter01_split\
UnevenSplit\vol1\chapter02_split\
Saves a {name}_debug_signal.png file alongside the split pages (auto mode only). The image is 512 px wide with the same height as the source image. Each row is a horizontal bar whose length is proportional to the smoothed seam-detection signal at that row. Detected cut points are drawn as red lines. Use this to understand why a seam was or was not detected.
Runs the full split analysis but skips writing individual page image files. Useful in combination with --save-debug-signal to inspect the detection signal without producing any output pages. If --cbz is also set, CBZ creation is skipped with a note.
After creating the CBZ archive, deletes all individual page image files from the output folder. If the folder is then empty, it is also removed. Has no effect without --cbz.
- Band brightness diff — for each row, compares the average brightness of the 8 rows above vs. the 8 rows below. Large differences indicate a transition between pages.
- Sobel edge energy diff — computes horizontal edge energy per row using a vertical Sobel kernel, then diffs that energy across the same bands. Catches seams where brightness is similar but edge structure shifts.
- Both signals are normalized to
[0, 1]and summed so neither dominates. - The combined signal is smoothed with a 1D Gaussian (σ = 3.0) to suppress single-row noise.
- Local maxima above the threshold that are spaced at least
--min-page-heightapart are selected as seams. - Clean divide check — once the number of detected seams (and therefore pages) is known, the tool checks whether
imageHeight % pageCount == 0. If it does divide evenly, the detected seam Y-positions are discarded and replaced with perfectly uniform cuts atimageHeight / pageCount * i. This guarantees every output page is the same height with no remainder pixels, regardless of where the signal peaks landed.
Height (18432px) divides evenly by 12: using clean 1536px cuts.
If the height does not divide evenly, the original signal-detected seam positions are kept as-is.
dotnet build
dotnet run --project SplitImages