# How to Use ImageKit for Batch Image Processing: A Complete Rust CLI Guide

> Learn how to use ImageKit for powerful batch image processing with Rust. Effortlessly resize, watermark, and convert images in parallel using our intuitive CLI guide.

- Repository: [hzbd/imagekit](https://github.com/hzbd/imagekit)
- Tags: how-to-guide
- Published: 2026-03-03

---

**ImageKit processes entire directories of images in parallel using Rayon, offering batch resizing, multilingual watermarking, and format conversion through a unified CLI that orchestrates operations across [`src/cli.rs`](https://github.com/hzbd/imagekit/blob/main/src/cli.rs), [`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs), and [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs) without manual thread management.**

ImageKit, available in the `hzbd/imagekit` repository, is a Rust-based command-line utility designed for high-throughput batch image processing. The tool automatically distributes workload across CPU cores while bundling required fonts for consistent watermark rendering. This guide covers how to leverage ImageKit’s architecture for efficient batch operations on large image collections.

## Architecture Overview for Batch Operations

ImageKit separates concerns across four primary components to ensure reliable parallel processing:

- **CLI Definition ([`src/cli.rs`](https://github.com/hzbd/imagekit/blob/main/src/cli.rs))**: Parses command-line arguments using **clap**, handling input/output paths, resize dimensions (`--width`, `--height`), watermark options, quality settings, and output formats through a strongly-typed `Cli` struct.

- **Orchestration Layer ([`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs))**: Contains the public `run` function that validates output directories, loads embedded fonts via [`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs), collects image paths using **walkdir**, and drives parallel execution through **Rayon**’s `par_iter()`.

- **Asset Management ([`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs))**: Embeds TrueType/OpenType fonts (`Roboto-Regular.ttf`, `SourceHanSansSC-Regular.otf`, `NotoSansThai-Regular.ttf`) using **rust-embed**, ensuring watermark rendering remains independent of external filesystem dependencies.

- **Image Processor ([`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs))**: Implements the per-image workflow in `process_image`, handling decoding, Lanczos3 resizing, multilingual text layout with **rusttype**, and format-aware encoding respecting quality parameters.

## Basic Batch Resizing

To resize an entire directory while preserving aspect ratios, specify the target width or height. ImageKit automatically calculates the complementary dimension using the `image` crate’s resizing logic in [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs).

```bash
./target/release/imagekit \
    -i path/to/input_dir \
    -o path/to/output_dir \
    --width 1200

```

*This command resizes every image to 1200px width; height scales automatically to maintain proportions.*

## Batch Processing with Quality Control

Control output quality for lossy formats or adjust compression levels for PNGs using the `--quality` flag. When set to `100` for JPEG output, ImageKit disables lossy compression entirely according to the encoder logic in [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs).

```bash
./target/release/imagekit \
    -i photos/raw \
    -o photos/resized \
    --width 1920 \
    --quality 100

```

*Quality values map directly to encoder settings: 100 yields lossless JPEG, while 85 provides balanced compression for WebP or PNG outputs.*

## Adding Multilingual Watermarks to Batches

ImageKit supports mixed-script watermarks through three embedded fonts covering Latin, CJK, and Thai characters. The `--watermark-position` flag accepts cardinal directions (`se` for South-East, `north` for top-center, etc.) parsed in [`src/cli.rs`](https://github.com/hzbd/imagekit/blob/main/src/cli.rs).

```bash
./target/release/imagekit \
    -i assets/images \
    -o assets/watermarked \
    --watermark-text "你好, World! – 示例水印" \
    --watermark-position se \
    --font-size 32 \
    --watermark-color ffffff80

```

*The semi-transparent white watermark (`ffffff80`) renders correctly across scripts because [`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs) bundles fonts with complementary glyph coverage.*

## Converting Image Formats in Bulk

Force specific output formats regardless of input type using `--output-format`. ImageKit handles the encoding transition in [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs), automatically adjusting pipeline parameters for PNG, WebP, or JPEG outputs.

```bash
./target/release/imagekit \
    -i collection/jpgs \
    -o collection/pngs \
    --output-format png \
    --quality 85

```

*For PNG outputs, quality settings translate to compression levels rather than lossy quantization.*

## Full-Featured Batch Commands

Combine resizing, watermarking, and format conversion in single invocations. The `run` function in [`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs) processes these operations sequentially per image while maintaining parallel execution across the batch.

```bash
./target/release/imagekit \
    -i src_images \
    -o processed \
    --width 1024 \
    --height 768 \
    --watermark-text "© 2026 Company" \
    --watermark-position north \
    --font-size 28 \
    --watermark-color 000000FF \
    --output-format webp \
    --quality 90

```

*This applies fixed dimensions (1024×768), places an opaque black watermark at the top center, and converts to WebP with quality 90.*

## How Parallel Processing Works Under the Hood

ImageKit achieves multi-core batch processing without manual thread management through a specific pipeline in [`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs):

1. **Directory Traversal**: Uses `walkdir::WalkDir` to recursively collect all image paths from the input directory into a `Vec<PathBuf>`.

2. **Parallel Iteration**: Feeds the collected paths to Rayon’s `par_iter()`, which automatically distributes images across available CPU cores.

3. **Per-Image Pipeline**: Each parallel thread executes `processor::process_image`, performing I/O, Lanczos3 resizing, watermark rasterization, and encoding independently.

All heavy operations—including decoding, scaling, and encoding—execute in parallel, making ImageKit suitable for high-resolution photo collections where single-threaded processing would create bottlenecks.

## Summary

- ImageKit provides **batch image processing** through a Rust CLI that combines **clap** for argument parsing, **walkdir** for directory traversal, and **Rayon** for parallel execution.
- The `run` function in [`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs) orchestrates the workflow, while [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs) handles per-image resizing, multilingual watermarking, and format conversion.
- Embedded fonts in [`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs) ensure reliable watermark rendering without external dependencies.
- Commands support aspect-ratio-preserving resizes, quality-controlled encoding, and mixed-script text overlays through a unified interface.

## Frequently Asked Questions

### How does ImageKit handle different image formats in the same batch?

ImageKit uses the `image` crate’s dynamic decoding in [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs) to automatically detect input formats during the `image::open` call. The tool processes each file according to its detected format while allowing you to standardize outputs using `--output-format`, enabling mixed-format input directories to convert to uniform output types in a single batch operation.

### Can I use custom fonts for watermarks instead of the embedded ones?

Currently, ImageKit relies on the three fonts bundled in [`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs) via **rust-embed** (`Roboto-Regular.ttf`, `SourceHanSansSC-Regular.otf`, `NotoSansThai-Regular.ttf`). The processor automatically selects appropriate fonts for detected Unicode ranges. To use custom typefaces, you would need to modify [`src/assets.rs`](https://github.com/hzbd/imagekit/blob/main/src/assets.rs) to embed additional font files and rebuild the binary.

### What resizing filter does ImageKit use for batch operations?

According to [`src/processor.rs`](https://github.com/hzbd/imagekit/blob/main/src/processor.rs), ImageKit applies the **Lanczos3** filter when resizing images. This filter provides high-quality downscaling and upscaling by sampling a larger pixel area with weighted contributions, preserving edge sharpness better than bilinear or nearest-neighbor methods during batch transformations.

### How does ImageKit prevent memory exhaustion when processing thousands of images?

The tool uses **Rayon**’s work-stealing thread pool in [`src/lib.rs`](https://github.com/hzbd/imagekit/blob/main/src/lib.rs) to limit concurrent operations to the number of logical CPU cores, preventing uncontrolled memory growth. Each `par_iter()` thread processes one image at a time through the complete pipeline (open → resize → watermark → save) before accepting new work, ensuring that memory usage scales with thread count rather than total batch size.