Skip to content

DuckyMomo20012/gm-toolkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Book Page Processor

A modern TypeScript tool using Google zx to automatically process scanned book images with rotation and optional page splitting. Designed for preprocessing scanned documents before OCR to improve text recognition accuracy.

Quick Start

# Install dependencies
pnpm install

# Place images in dist/images/
# Then run:
pnpm run process

Examples:

  • page_rot90.jpg → Rotates 90° clockwise
  • page_split.jpg → Splits into left & right pages
  • page_rot90_split.jpg → Rotates then splits
  • page_l+50px.jpg → Splits with left page 50px wider

Problem Statement

When scanning books, pages are often captured with issues that need correction:

  1. Orientation: Pages may be rotated or skewed
  2. Dual pages: Landscape scans contain two pages side-by-side that need splitting
  3. Alignment: Split position may not be perfectly centered

Solution

This script provides flexible processing with multiple operations:

  1. Image rotation - Rotate images by any angle (90°, 180°, 270°, or arbitrary angles for skew correction)
  2. Optional splitting - Split dual-page images into separate pages (opt-in via filename)
  3. Relative adjustments - Shift the split line left or right from center
  4. Page-specific adjustments - Specify adjustments relative to which page needs more/less content
  5. Absolute positioning - Define exact pixel position for the split line

Requirements

  • Node.js (v14 or higher)
  • GraphicsMagick (gm command) - See installation instructions below

2. Install GraphicsMagick

GraphicsMagick must be installed separately. See installation instructions below.

Linux (Ubuntu/Debian)

Method 1: Package Manager (Recommended)

sudo apt-get update
sudo apt-get install graphicsmagick

Method 2: From Source

# Install dependencies
sudo apt-get install build-essential libpng-dev libjpeg-dev libwebp-dev

# Download latest stable version
wget https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.42/GraphicsMagick-1.3.42.tar.gz

# Extract
tar xzf GraphicsMagick-1.3.42.tar.gz
cd GraphicsMagick-1.3.42

# Configure, compile, and install
./configure --enable-shared
make
sudo make install
sudo ldconfig

Verify installation:

gm version

macOS

Method 1: Homebrew (Recommended)

# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install GraphicsMagick
brew install graphicsmagick

Method 2: MacPorts

sudo port install GraphicsMagick

Method 3: From Source

# Install Xcode Command Line Tools
xcode-select --install

# Download latest version
curl -O https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.42/GraphicsMagick-1.3.42.tar.gz

# Extract and build
tar xzf GraphicsMagick-1.3.42.tar.gz
cd GraphicsMagick-1.3.42
./configure --enable-shared
make
sudo make install

Verify installation:

gm version

Windows

Method 1: Installer (Recommended)

  1. Visit the GraphicsMagick Downloads page
  2. Download the Windows installer (e.g., GraphicsMagick-1.3.42-Q16-win64-dll.exe)
  3. Run the installer
  4. During installation:
    • Check "Add application directory to your system path"
    • Check "Install development headers and libraries" if needed
  5. Restart your terminal/command prompt

Method 2: Chocolatey

# Install Chocolatey if not installed
# Visit https://chocolatey.org/install

# Install GraphicsMagick
choco install graphicsmagick

Method 3: Windows Subsystem for Linux (WSL)

# Inside WSL Ubuntu
sudo apt-get update
sudo apt-get install graphicsmagick

Verify installation (Command Prompt or PowerShell):

gm version

Note for Windows users: To run the bash script, you'll need:

  • Git Bash (comes with Git for Windows)
  • WSL (Windows Subsystem for Linux)
  • Cygwin

Building from Source (All Platforms)

Latest Version:


Step 1: Install Dependencies

GraphicsMagick needs development libraries for image format support. Install the formats you need:

Ubuntu/Debian:

# Build essentials
sudo apt-get update
sudo apt-get install build-essential

# Image format libraries (install what you need)
sudo apt-get install \
  libpng-dev \        # PNG support
  libjpeg-dev \       # JPEG support
  libwebp-dev \       # WebP support
  libtiff-dev \       # TIFF support
  libfreetype6-dev \  # TrueType font support
  liblcms2-dev \      # Color management
  libxml2-dev \       # XML support
  zlib1g-dev          # Compression

CentOS/RHEL/Fedora:

# Build tools
sudo yum groupinstall "Development Tools"
sudo yum install gcc gcc-c++ make

# Image format libraries
sudo yum install \
  libpng-devel \
  libjpeg-devel \
  libwebp-devel \
  libtiff-devel \
  freetype-devel \
  lcms2-devel \
  libxml2-devel \
  zlib-devel

macOS (requires Homebrew or MacPorts):

# Install Xcode Command Line Tools first
xcode-select --install

# Using Homebrew
brew install \
  libpng \
  jpeg \
  webp \
  libtiff \
  freetype \
  little-cms2 \
  libxml2 \
  zlib

# Using MacPorts (alternative)
sudo port install \
  libpng \
  jpeg \
  webp \
  tiff \
  freetype \
  lcms2 \
  libxml2 \
  zlib

Windows (using MSYS2/MinGW):

# Install MSYS2 from https://www.msys2.org/
# Open MSYS2 terminal and run:

pacman -S base-devel mingw-w64-x86_64-toolchain

pacman -S \
  mingw-w64-x86_64-libpng \
  mingw-w64-x86_64-libjpeg-turbo \
  mingw-w64-x86_64-libwebp \
  mingw-w64-x86_64-libtiff \
  mingw-w64-x86_64-freetype \
  mingw-w64-x86_64-lcms2 \
  mingw-w64-x86_64-libxml2 \
  mingw-w64-x86_64-zlib

Step 2: Download GraphicsMagick Source

# Download latest stable version (1.3.42 as of Dec 2025)
wget https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.42/GraphicsMagick-1.3.42.tar.gz

# Alternative using curl:
curl -O https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/1.3.42/GraphicsMagick-1.3.42.tar.gz

# Or download via browser from:
# https://sourceforge.net/projects/graphicsmagick/files/graphicsmagick/

Step 3: Extract the Archive

tar xzf GraphicsMagick-1.3.42.tar.gz
cd GraphicsMagick-1.3.42

Step 4: Explore Configuration Options

# See all available configure options
./configure --help | less

# Check what dependencies are detected on your system
./configure --help | grep -A 2 "with-"

Step 5: Configure the Build

Important Configure Flags:

Flag Purpose Recommendation
--prefix=/path Installation location Default: /usr/local
--enable-shared Build shared libraries Required for most uses
--with-quantum-depth=N Color depth (8, 16, or 32) Use 16 for best quality
--with-png=yes Enable PNG support Essential for this script
--with-jpeg=yes Enable JPEG support Essential for this script
--with-webp=yes Enable WebP support Essential for this script
--with-tiff=yes Enable TIFF support Optional but recommended
--with-freetype=yes TrueType font support Optional
--with-lcms2=yes Color management Recommended for quality
--with-xml=yes XML support Optional
--with-zlib=yes Compression Recommended

Minimal Configuration (PNG, JPEG, WebP only):

./configure \
  --enable-shared \
  --with-quantum-depth=16 \
  --with-png=yes \
  --with-jpeg=yes \
  --with-webp=yes

Recommended Configuration (all common formats):

./configure \
  --prefix=/usr/local \
  --enable-shared \
  --with-quantum-depth=16 \
  --with-png=yes \
  --with-jpeg=yes \
  --with-webp=yes \
  --with-tiff=yes \
  --with-freetype=yes \
  --with-lcms2=yes \
  --with-xml=yes \
  --with-zlib=yes

Full-featured Configuration:

./configure \
  --prefix=/usr/local \
  --enable-shared \
  --enable-static \
  --with-quantum-depth=16 \
  --with-png=yes \
  --with-jpeg=yes \
  --with-webp=yes \
  --with-tiff=yes \
  --with-freetype=yes \
  --with-lcms2=yes \
  --with-xml=yes \
  --with-zlib=yes \
  --with-modules \
  --enable-largefile

User-local Installation (no sudo needed):

./configure \
  --prefix=$HOME/local \
  --enable-shared \
  --with-quantum-depth=16 \
  --with-png=yes \
  --with-jpeg=yes \
  --with-webp=yes

Understanding the Configure Output:

After running ./configure, you'll see a summary like:

GraphicsMagick is configured as follows:
...
PNG support:     yes
JPEG support:    yes
WebP support:    yes
TIFF support:    no
...

⚠️ Check this output carefully! If a format shows "no", the library wasn't found. Install the missing -dev or -devel package and rerun configure.


Step 6: Compile

# Basic compilation
make

# Faster compilation using multiple CPU cores
make -j$(nproc)           # Linux (uses all cores)
make -j$(sysctl -n hw.ncpu)  # macOS (uses all cores)
make -j4                  # Use exactly 4 cores

Note: Compilation takes 5-15 minutes depending on your system.


Step 7: Test the Build (Optional but Recommended)

# Run the test suite
make check

# If tests fail, check config.log for details
less config.log

Step 8: Install

# System-wide installation (requires sudo)
sudo make install

# Update shared library cache (Linux only)
sudo ldconfig

# User-local installation (if configured with --prefix=$HOME/local)
make install
export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH

Step 9: Verify Installation

# Check if gm is in PATH
which gm
# Should output: /usr/local/bin/gm

# Check version and supported formats
gm version

# Look for these lines in the output:
# Feature Support:
#   Native Blob Support: yes
#   PNG: yes
#   JPEG: yes
#   WebP: yes

Example successful output:

GraphicsMagick 1.3.42 2023-03-18 Q16 http://www.GraphicsMagick.org/
Copyright (C) 2002-2023 GraphicsMagick Group.

Feature Support:
  Native Blob Support: yes
  Native File Support: yes

  PNG: yes
  JPEG: yes
  WebP: yes
  TIFF: yes

Step 10: Make It Permanent

Add to PATH (if installed to custom location):

# For bash
echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

# For zsh
echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.zshrc
echo 'export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH' >> ~/.zshrc
source ~/.zshrc

Troubleshooting Installation

"gm: command not found"

  • Ensure GraphicsMagick is installed: check with your package manager
  • Check if it's in PATH: echo $PATH
  • Find installation location: find /usr -name "gm" 2>/dev/null
  • Add to PATH if needed:
    export PATH=$PATH:/usr/local/bin
    # Add to ~/.bashrc or ~/.zshrc to make permanent

Missing format support (e.g., WebP)

  • Check supported formats: gm version

  • Reinstall with format libraries:

    # Ubuntu/Debian
    sudo apt-get install libwebp-dev libpng-dev libjpeg-dev
    
    # macOS
    brew install webp libpng jpeg
    
    # Then rebuild GraphicsMagick from source

Permission denied during installation

  • Use sudo for system-wide installation
  • Or install to user directory:
    ./configure --prefix=$HOME/local
    make install
    export PATH=$HOME/local/bin:$PATH

Build errors on macOS

  • Install Xcode Command Line Tools: xcode-select --install
  • Check for conflicting installations: brew list | grep magick
  • Remove ImageMagick if installed: brew uninstall imagemagick

Directory Structure

.
├── package.json      # Node.js dependencies
├── tsconfig.json     # TypeScript configuration
├── src/
│   └── process.ts    # Main processing script (TypeScript + zx)
├── dist/
│   ├── images/       # Input directory (source scanned images)
│   └── output/       # Output directory (created automatically)
├── gm-batch.sh       # Legacy bash script (deprecated)
└── README.md

Installation

1. Install Node.js Dependencies

pnpm install

This installs:

  • zx: Google's shell scripting tool for JavaScript/TypeScript
  • tsx: TypeScript execution engine
  • TypeScript: Type checking and compilation

Usage

Basic Usage

  1. Place your scanned images in the ./dist/images directory
  2. Run the script:
    pnpm run process
    # or directly with tsx:
    tsx src/process.ts
  3. Processed images will appear in ./dist/output directory

Default Behavior

Images are NOT split by default. Without any filename hints, images are simply copied (with rotation applied if specified):

  • scan001.jpgscan001.jpg (copied to output)
  • scan002_rot90.jpgscan002.jpg (rotated 90°, then saved)

To split an image, you must add a split hint to the filename.

Filename-Based Operations

Rename your files to include operation hints in the filename (before the extension). You can combine multiple operations.

Image Rotation (_rot or _rotate)

Rotate the image. Supports any angle (positive for clockwise, negative for counter-clockwise):

  • scan001_rot90.jpg - Rotate 90° clockwise
  • scan002_rotate180.jpg - Rotate 180° (upside down)
  • scan003_rot270.jpg - Rotate 270° clockwise (or 90° counter-clockwise)
  • scan004_rot45.jpg - Rotate 45° clockwise (creates padded output)
  • scan005_rot-15.jpg - Rotate 15° counter-clockwise (minus sign for CCW)
  • scan006_rot22.5.jpg - Rotate 22.5° clockwise (decimal angles supported)

Supported angles: Any positive or negative number, including decimals

Note:

  • After rotation, the image dimensions change based on the angle
  • Non-90° rotations will add padding to maintain rectangular shape

Output: Rotated image without _rot* suffix (e.g., scan001_rot90.jpgscan001.jpg)

Page Splitting (_split or _sp)

Split a dual-page image into left and right pages at the center (50% width):

  • scan001_split.jpg - Split at center → scan001_l.jpg + scan001_r.jpg
  • scan002_sp.jpg - Same as above (short form)

Note: Splitting is opt-in. Files without a split hint are NOT split.

Combining Rotation with Splitting

You can combine rotation with splitting. Place rotation hint before the split hint:

  • scan001_rot90_split.jpg - Rotate 90°, then split at center
  • scan002_rot270_sp.jpg - Rotate 270°, then split at center

Advanced: Split with Adjustments

Move the split line from the center for precise control:

Left Page Adjustments (_l or _left)

Move the split line to give the left page more or less content:

  • scan001_l+50px.jpg - Left page gets 50px more (split line moves right)
  • scan001_left+50px.jpg - Same as above (verbose form)
  • scan001_l-30px.jpg - Left page gets 30px less (split line moves left)

Note: Using _l or _left automatically enables splitting.

Example:

  • Image width: 2000px
  • Default split: 1000px
  • scan001_l+50px.jpg: Split at 1050px (left: 1050px, right: 950px)
  • scan001_l-50px.jpg: Split at 950px (left: 950px, right: 1050px)
Right Page Adjustments (_r or _right)

Move the split line to give the right page more or less content:

  • scan002_r+50px.jpg - Right page gets 50px more (split line moves left)
  • scan002_right-30px.jpg - Right page gets 30px less (split line moves right)

Example:

  • Image width: 2000px
  • Default split: 1000px
  • scan002_r+50px.jpg: Split at 950px (left: 950px, right: 1050px)
  • scan002_r-50px.jpg: Split at 1050px (left: 1050px, right: 950px)

Note: Using _r or _right automatically enables splitting.

Absolute Position (_s or _split)

Specify exact pixel position from the left edge:

  • scan003_s1200px.jpg - Split at exactly 1200px from left
  • scan003_split1200px.jpg - Same as above (verbose form)

Note: Using _s with a pixel value automatically enables splitting.

Example:

  • Image width: 2400px
  • scan003_s1200px.jpg: Split at 1200px (left: 1200px, right: 1200px)
Combining Everything

You can combine rotation with any split adjustment:

  • scan001_rot90_l+50px.jpg - Rotate 90°, then give left page 50px more
  • scan002_rot270_s1500px.jpg - Rotate 270°, then split at exactly 1500px
  • scan003_rot180_r+30px.jpg - Rotate 180°, then give right page 30px more
  • scan004_rot-5.5_l+100px.jpg - Rotate 5.5° CCW, then adjust left page

Output Naming

The script removes operation suffixes from output filenames:

Input Filename Output(s)
page001.jpg page001.jpg (copied)
page002_rot90.jpg page002.jpg (rotated)
page003_split.jpg page003_l.jpg, page003_r.jpg
page004_rot90_split.jpg page004_l.jpg, page004_r.jpg
page005_l+50px.jpg page005_l.jpg, page005_r.jpg
page006_rot180_r-30px.png page006_l.png, page006_r.png
page007_rot270_s1500px.webp page007_l.webp, page007_r.webp

Supported Image Formats

  • PNG (.png)
  • JPEG (.jpg, .jpeg)
  • WebP (.webp)

All formats are case-insensitive (e.g., .PNG, .JPG also work).

How It Works

Step-by-Step Process

  1. Scan Input Directory: Iterates through all files in ./dist/images/
  2. Filter Images: Only processes PNG, JPG, JPEG, and WebP files
  3. Parse Filename: Detects rotation and split/adjustment hints using regex patterns
  4. Apply Rotation (if specified): Rotates the image and recalculates dimensions
  5. Check Split Mode: Determines if splitting is needed based on filename hints
  6. Calculate Split Position (if splitting):
    • Default: width / 2 (using rotated dimensions if applicable)
    • With hints: Adjusts split position based on offset
  7. Validate (if splitting): Ensures split position is within valid range (0 < position < width)
  8. Process Image:
    • With splitting: Crop into left and right pages using GraphicsMagick's -crop command with +repage
    • Without splitting: Copy or save rotated image
  9. Save Output: Writes processed images to ./dist/output/ with cleaned filenames
  10. Cleanup: Removes temporary rotated files

Technical Details

Built with Google zx for modern shell scripting in JavaScript.

GraphicsMagick Commands Used:

# Rotation
gm convert input.jpg -rotate 90 output.jpg

# Crop (splitting)
gm convert input.jpg -crop WIDTHxHEIGHT+X_OFFSET+Y_OFFSET +repage output.jpg
  • Rotation angles: Any positive or negative number (including decimals)
  • WIDTH x HEIGHT: Dimensions of cropped area
  • +X_OFFSET +Y_OFFSET: Starting position (top-left corner)
  • +repage: Removes the virtual canvas, resetting image to cropped dimensions

Regex Patterns Used:

_rot(ate)?(-?[0-9]+(\.[0-9]+)?)(_|$)  # Rotation: _rot90, _rot-15, _rot22.5, _rotate45
_l(eft)?([+-][0-9]+)px$               # Left adjustments: _l+50px, _left-30px
_r(ight)?([+-][0-9]+)px$              # Right adjustments: _r+50px, _right-30px
_rot(ate)?(-?[0-9]+(?:\.[0-9]+)?)(?:_|$)  # Rotation: _rot90, _rot-15, _rot22.5
_sp(lit)?(?:_|$)                          # Simple split: _split, _sp
_l(eft)?([+-][0-9]+)px$                   # Left adjustments: _l+50px, _left-30px
_r(ight)?([+-][0-9]+)px$                  # Right adjustments: _r+50px, _right-30px
_s(plit)?([0-9]+)px$                      # Absolute position: _s1200px, _split1200px

Example Workflow

Scenario: Mixed Scans

You have scanned pages with varying needs:

dist/images/
├── chapter1_page001.jpg              # Perfect - just copy
├── chapter1_page002_rot90.jpg        # Needs 90° rotation only
├── chapter1_page003_split.jpg        # Needs splitting at center
├── chapter1_page004_rot90_split.jpg  # Rotate 90°, then split
├── chapter1_page005_l+40px.jpg       # Split with left page 40px more
├── chapter1_page006_rot270_r+60px.jpg # Rotate 270°, split with right adjusted
└── chapter1_page007_rot180.png       # Rotate 180° only

Run the script:

pnpm run process

Output:

dist/output/
├── chapter1_page001.jpg              # Copied as-is
├── chapter1_page002.jpg              # Rotated 90°
├── chapter1_page003_l.jpg            # Split at center
├── chapter1_page003_r.jpg
├── chapter1_page004_l.jpg            # Rotated 90°, then split
├── chapter1_page004_r.jpg
├── chapter1_page005_l.jpg            # Split with left 40px wider
├── chapter1_page005_r.jpg            # Right 40px narrower
├── chapter1_page006_l.jpg            # Rotated 270°, right adjusted
├── chapter1_page006_r.jpg
└── chapter1_page007.png              # Rotated 180°

## Determining the Right Split Offset

To find the correct offset for images that need splitting:

1. **Visual Inspection**: Open image in an image viewer that shows cursor
   coordinates
2. **Measure Split Line**: Hover cursor over the gutter between pages and note
   the x-coordinate
3. **Calculate Offset**:

   - If split should be at 1100px and image width is 2000px:
   - Default split: 1000px
   - Needed adjustment: 1100 - 1000 = +100px
   - Rename: `image_l+100px.jpg` or `image_s1100px.jpg`

4. **Test and Refine**:
   ```bash
   # Test with one image first
   cp dist/images/scan001.jpg dist/images/test_l+50px.jpg
   pnpm run process
   # Check dist/output/test_l.jpg and dist/output/test_r.jpg
   # Adjust offset as needed

Common Use Cases

Rotate Single-Page Scans

If you have portrait pages scanned sideways (no splitting needed):

# Single page that needs rotation
mv scan001.jpg scan001_rot90.jpg

# Batch rename all files in dist/images
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_rot90.jpg"
done
cd ../..

Split Dual-Page Scans

If you have landscape scans with two pages side-by-side:

# Add split hint to dual-page scans
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_split.jpg"
done
cd ../..

Rotate Then Split

If portrait pages were scanned in landscape orientation with two pages:

# Rotate 90° then split
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_rot90_split.jpg"
done
cd ../..

Skewed Scans (Minor Angle Correction)

If pages were scanned at a slight angle and need correction:

# Rotate 2.5° counter-clockwise to straighten
mv scan001.jpg scan001_rot-2.5.jpg

# Rotate 1.8° clockwise
mv scan002.jpg scan002_rot1.8.jpg

Note: Small angle corrections will add minimal padding, but may be useful for improving OCR accuracy on skewed scans.

Upside-Down Scans

If pages were scanned upside-down:

mv scan001.jpg scan001_rot180.jpg

Mixed Orientation with Adjustments

For pages that need both rotation and split adjustment:

# Rotate 90° and give left page 50px more
mv scan001.jpg scan001_rot90_l+50px.jpg

# Rotate 270° and split at exact position
mv scan002.jpg scan002_rot270_s1400px.jpg

Troubleshooting

Error: "geometry dimensions are zero"

  • Cause: GraphicsMagick couldn't determine crop dimensions
  • Solution: Ensure image file is valid and not corrupted

Error: "Invalid split position"

  • Cause: Calculated split position is outside image boundaries
  • Solution: Check your offset value - it may be too large or negative

Images not processed

  • Cause: File extension not recognized
  • Solution: Ensure files have .png, .jpg, .jpeg, or .webp extensions

Output images have wrong dimensions

  • Cause: Incorrect offset calculation
  • Solution:
    1. Check original image dimensions: gm identify input.jpg
    2. Verify offset math: For 2000px wide image with _l+50px, split should be at 1050px
    3. Test with absolute positioning: _s1050px

Advanced Usage

Customizing Directories

Edit src/process.ts to change input/output directories:

const INPUT_DIR = "./my_scans";
const OUTPUT_DIR = "./processed_pages";

Batch Operations with Shell

Rotate all images

# Add 90° rotation to all JPG files
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_rot90.jpg"
done
cd ../..

Add split to all dual-page scans

cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_split.jpg"
done
cd ../..

Add consistent rotation and split with offset

# Rotate 90° and add left offset to all images
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_rot90_l+50px.jpg"
done
cd ../..

Processing Specific Files

# Process only specific files by moving them temporarily
mkdir -p dist/images_temp
mv dist/images/page{010..020}.jpg dist/images_temp/
# Edit src/process.ts to use dist/images_temp as INPUT_DIR
pnpm run process

Extending the Script

The src/process.ts file is written in TypeScript using Google zx. You can easily extend it with full type safety:

// Add new image formats
const validExtensions = [".png", ".jpg", ".jpeg", ".webp", ".tiff", ".bmp"];

// Add custom operations
if (name.includes("_custom")) {
  // Your custom logic here
}

// Change default behavior
const splitMode = true; // Split all images by default

Why TypeScript + zx?

Google zx with TypeScript provides several advantages over bash:

  • Type Safety: Catch errors at compile time with TypeScript
  • Modern JavaScript: Familiar syntax for Node.js developers
  • Better error handling: Try/catch blocks and proper error messages
  • Colored output: Built-in chalk for better UX
  • Cross-platform: Works consistently on Linux, macOS, and Windows
  • Async/await: Clean handling of shell commands
  • Easy maintenance: More readable and maintainable than bash
  • IDE Support: Full autocomplete and type checking

Script Customization

Adding New Image Formats

Edit src/process.ts:

const validExtensions = [".png", ".jpg", ".jpeg", ".webp", ".tiff", ".bmp"];

Changing Default Split Ratio

To split at 40/60 instead of 50/50, modify src/process.ts:

// Change this line:
let splitPosition = Math.floor(width / 2);

// To:
let splitPosition = Math.floor(width * 0.4);

Making Split the Default

To split all images by default (without requiring _split suffix), edit

Changing Default Behavior (Split All Images)

To split all images by default without requiring a _split hint, modify src/process.ts:

// Change this line:
let splitMode = false;

// To:
let splitMode = true;

Performance

  • Speed: Depends on GraphicsMagick performance and image size
  • Typical: ~1-2 seconds per 2000x3000px image on modern hardware
  • Memory: Processes one image at a time, minimal RAM usage
  • Parallel Processing: Script processes images sequentially; for parallel processing, you could modify src/process.ts to use Promise.all()

Migration from Bash Script

The legacy gm-batch.sh script is still included but deprecated. Key differences in the new TypeScript script:

  1. Type Safety: Full TypeScript support with compile-time checks
  2. Splitting is opt-in: Add _split or _sp to filenames to split images
  3. Better error handling: Clear error messages with colored output
  4. Modern syntax: TypeScript instead of bash
  5. Cross-platform: Works on Windows, macOS, and Linux

To migrate:

# Old behavior (always splits):
# images/scan001.jpg → output/scan001_l.jpg + output/scan001_r.jpg

# New behavior (opt-in splitting):
# dist/images/scan001.jpg → dist/output/scan001.jpg (no split)
# dist/images/scan001_split.jpg → dist/output/scan001_l.jpg + scan001_r.jpg

# To keep old behavior, rename files to include _split:
cd dist/images
for f in *.jpg; do
  mv "$f" "${f%.jpg}_split.jpg"
done
cd ../..

Note: All examples use pnpm. If using npm or yarn, replace pnpm with npm or yarn.

If you prefer the old bash script, you can still use it:

chmod +x gm-batch.sh
./gm-batch.sh

Contributing

Suggestions for improvements:

  • Add GUI for visual split line adjustment
  • Implement automatic spine detection using image processing
  • Add support for batch correction based on margin detection
  • Create preview mode to visualize operations before processing
  • Add support for batch processing via config file

Pull requests are welcome!

License

This project is provided as-is for educational and practical use. Modify as needed for your workflow.

About

A Typescript GraphicsMagick wrapper for basic image operations

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published