A high-performance image format batch conversion CLI tool written in pure Rust. Convert between 20+ image formats with parallel processing, resizing, cropping, filters, watermarks, EXIF handling, quality comparison, presets, and more β all from a single binary with zero C dependencies.
- 20+ Image Formats β JPEG, PNG, GIF, BMP, TIFF, TGA, ICO, QOI, PNM, OpenEXR, HDR, Farbfeld, WebP, SVG, AVIF, JPEG XL, DDS, PCX, Ultra HDR, APNG
- Batch Conversion β Convert all images in a directory at once with parallel processing (rayon)
- Multi-Format Output β Convert a single input to multiple formats simultaneously (
--to png,webp,jpeg) - Image Resizing β Resize during conversion with flexible aspect ratio controls
- Image Cropping β Crop specific regions with
--crop x,y,w,h - Rotation & Flip β Rotate 90/180/270Β° and flip horizontal/vertical
- Color Filters β Grayscale, invert, sepia tone effects
- Blur & Sharpen β Gaussian blur and unsharp mask
- Brightness/Contrast/Gamma β Fine-tune image exposure and tone
- Text Watermark β Add text watermarks with position, opacity, and custom font support
- Image Overlay β Composite logo or image overlays with position and opacity control
- EXIF Auto-Orient β Automatically correct image orientation from EXIF data
- EXIF Preservation β Copy EXIF metadata from source to output (JPEGβJPEG)
- Image Info β Display image metadata without conversion (
--info) - Quality Comparison β SSIM/PSNR metrics between two images (
--compare) - Deduplication β Skip identical files via SHA-256 hash comparison (
--skip-identical) - Conversion Presets β Built-in presets for web, thumbnail, print, social (
--preset) - Quality Control β Fine-tune lossy compression quality for JPEG, WebP, and AVIF
- SVG β Raster β Rasterize SVG (resvg) or trace raster images to SVG (vtracer)
- Animation β Extract frames from animated GIF, or assemble images into animated GIF
- Dry-Run Mode β Preview conversion plans without writing any files
- Progress Bar β Real-time progress display for batch operations (indicatif)
- Pure Rust β No C compiler required. Builds on Linux, macOS, and Windows
- Library + Binary β Use as a CLI tool or integrate the library crate into your project
| Format | Extensions | Read | Write | Quality | Feature | Crate |
|---|---|---|---|---|---|---|
| JPEG | .jpg, .jpeg |
β | β | β (default: 85) | β | image |
| PNG | .png |
β | β | β | β | image |
| GIF | .gif |
β | β | β | β | image |
| BMP | .bmp |
β | β | β | β | image |
| TIFF | .tif, .tiff |
β | β | β | β | image |
| TGA | .tga |
β | β | β | β | image |
| ICO | .ico |
β | β | β | β | image |
| QOI | .qoi |
β | β | β | β | image |
| PNM | .ppm, .pgm, .pbm, .pam |
β | β | β | β | image |
| OpenEXR | .exr |
β | β | β | β | image |
| HDR | .hdr |
β | β | β | β | image |
| Farbfeld | .ff |
β | β | β | β | image |
| WebP | .webp |
β | β | β (lossy default: 75) | β | zenwebp |
| SVG | .svg |
β | β | β | β | resvg / vtracer |
| AVIF | .avif |
β | β | β (default: 70) | avif |
ravif / rav1d |
| JPEG XL | .jxl |
β | β | β | jxl |
jxl-oxide |
| DDS | .dds |
β | β | β | dds |
image (dds) |
| PCX | .pcx |
β | β | β | pcx |
pcx |
| Ultra HDR | .uhdr |
stub | stub | β | ultrahdr |
β |
| APNG | .apng |
β | stub | β | apng |
image (png) |
Feature-gated formats require the corresponding feature flag at build time (e.g.,
cargo build --features avif,jxl,pcx).
# Standard build
cargo build --release
# With all optional formats
cargo build --release --features avif,jxl,dds,pcx,compare,dedup
# With specific features
cargo build --release --features "avif,compare"The compiled binary will be at target/release/imgconv (or imgconv.exe on Windows).
- Rust 1.70+ (2021 edition)
- No C compiler needed β all dependencies are pure Rust
imgconv [OPTIONS] --to <FORMAT> <INPUT>
# Single file conversion
imgconv photo.png --to jpeg
imgconv photo.jpg --to webp
imgconv photo.jpg --to webp --lossless
# Multiple formats at once
imgconv photo.bmp --to jpeg,webp,png
# Batch convert a directory
imgconv ./photos --to webp -o ./output
# Resize
imgconv photo.png --to jpeg --width 800
imgconv photo.png --to jpeg --width 800 --height 600 --keep-aspect
# Quality control
imgconv photo.png --to jpeg --quality 95
imgconv photo.png --to webp --lossy --quality 60
# Crop
imgconv photo.jpg --to png --crop 100,100,800,600
# Rotate & Flip
imgconv photo.jpg --to png --rotate 90
imgconv photo.jpg --to png --flip horizontal
# Color filters
imgconv photo.jpg --to png --grayscale
imgconv photo.jpg --to png --sepia
imgconv photo.jpg --to png --invert
# Blur & Sharpen
imgconv photo.jpg --to png --blur 2.0
imgconv photo.jpg --to png --sharpen 1.5
# Brightness / Contrast / Gamma
imgconv photo.jpg --to png --brightness 20 --contrast 1.5
imgconv photo.jpg --to png --gamma 2.2
# Text watermark
imgconv photo.jpg --to png --watermark "Β© 2026" --watermark-position bottom-right --watermark-opacity 0.5
# Image overlay
imgconv photo.jpg --to png --overlay logo.png --overlay-position center --overlay-opacity 0.7
# EXIF
imgconv photo.jpg --to jpeg --auto-orient
imgconv photo.jpg --to jpeg --preserve-exif
# Image info (no conversion)
imgconv photo.jpg --info
# Quality comparison (requires --features compare)
imgconv --compare original.jpg converted.webp
# Skip identical files (requires --features dedup)
imgconv ./photos --to webp -o ./output --skip-identical
# Presets
imgconv photo.jpg --preset web
imgconv photo.jpg --preset thumbnail
imgconv photo.jpg --preset print
imgconv photo.jpg --preset social
# SVG
imgconv icon.svg --to png --dpi 300
imgconv photo.png --to svg --svg-preset poster
# Animation
imgconv animated.gif --extract-frames --to png -o ./frames
imgconv ./frames --assemble-gif --frame-delay 50 -o ./output
# Dry-run & Verbose
imgconv ./photos --to webp --dry-run
imgconv ./photos --to webp -o ./output --verbose| Option | Short | Description | Default |
|---|---|---|---|
<INPUT> |
Input file or directory path (required) | ||
--to <FORMAT> |
Target format(s), comma-separated (required) | ||
--output <DIR> |
-o |
Output directory | Same as input |
--quality <1-100> |
Compression quality for lossy formats | Format default | |
--width <PX> |
Resize width in pixels | ||
--height <PX> |
Resize height in pixels | ||
--keep-aspect |
Preserve aspect ratio when both width and height set | false |
|
--crop <x,y,w,h> |
Crop region (x, y, width, height) | ||
--rotate <DEG> |
Rotate: 90, 180, 270 | ||
--flip <DIR> |
Flip: horizontal, vertical | ||
--grayscale |
Convert to grayscale | false |
|
--invert |
Invert colors | false |
|
--sepia |
Apply sepia tone | false |
|
--blur <SIGMA> |
Gaussian blur (sigma value) | ||
--sharpen <VALUE> |
Unsharp mask | ||
--brightness <INT> |
Brightness adjustment (+/-) | ||
--contrast <FLOAT> |
Contrast adjustment | ||
--gamma <FLOAT> |
Gamma correction | ||
--watermark <TEXT> |
Text watermark | ||
--watermark-position |
Watermark position | bottom-right |
|
--watermark-opacity |
Watermark opacity (0.0-1.0) | 0.5 |
|
--watermark-font |
TrueType font file path | Built-in | |
--overlay <FILE> |
Overlay image file path | ||
--overlay-position |
Overlay position | bottom-right |
|
--overlay-opacity |
Overlay opacity (0.0-1.0) | 1.0 |
|
--auto-orient |
Auto-correct EXIF orientation | false |
|
--no-auto-orient |
Disable EXIF orientation correction | ||
--preserve-exif |
Preserve EXIF metadata | false |
|
--info |
Show image info (no conversion) | false |
|
--compare <A> <B> |
Compare two images (SSIM/PSNR) | ||
--skip-identical |
Skip files with identical hash | false |
|
--preset <NAME> |
Conversion preset: web, thumbnail, print, social | ||
--lossy |
WebP lossy encoding | Default for WebP | |
--lossless |
WebP lossless encoding | ||
--dpi <DPI> |
SVG rasterization DPI | 96 |
|
--svg-preset <PRESET> |
SVG tracing preset: bw, poster, photo | default |
|
--overwrite |
Overwrite existing output files | false |
|
--dry-run |
Print conversion plan without executing | false |
|
--verbose |
Print detailed per-file conversion info | false |
|
--extract-frames |
Extract frames from animated GIF | false |
|
--assemble-gif |
Assemble images into animated GIF | false |
|
--frame-delay <MS> |
Frame delay in milliseconds | 100 |
|
--help |
-h |
Show help message |
| Preset | Format | Quality | Width | Height | Keep Aspect | Notes |
|---|---|---|---|---|---|---|
web |
WebP (lossy) | 80 | 1920 | β | β | Max width 1920px |
thumbnail |
JPEG | 70 | 200 | 200 | β | Square fit |
print |
TIFF | β | β | β | β | 300 DPI |
social |
JPEG | 85 | 1200 | 630 | β | OG image size |
| Code | Meaning |
|---|---|
0 |
All conversions succeeded |
1 |
Some conversions failed (partial success) |
2 |
All conversions failed, or argument error |
[dependencies]
imgconv = { path = ".", default-features = false }use std::path::Path;
use imgconv::convert::{convert_file, ConvertOptions};
use imgconv::format::ImageFormat;
fn main() -> Result<(), imgconv::error::ConvertError> {
let options = ConvertOptions {
target_formats: vec![ImageFormat::WebP, ImageFormat::Jpeg],
quality: Some(80),
output_dir: Some("./output".into()),
overwrite: false,
dry_run: false,
verbose: false,
..Default::default()
};
let results = convert_file(Path::new("photo.png"), &options)?;
for r in &results {
println!("{} -> {} ({} bytes)",
r.input_path.display(),
r.output_path.display(),
r.output_size,
);
}
Ok(())
}imgconv/
βββ src/
β βββ lib.rs # Library entry point, public API re-exports
β βββ main.rs # CLI binary (clap + indicatif)
β βββ format.rs # ImageFormat enum, extension detection
β βββ convert.rs # Conversion orchestrator (single file pipeline)
β βββ batch.rs # Batch processor (directory, parallel via rayon)
β βββ raster.rs # Raster codec (12 formats via image crate)
β βββ webp.rs # WebP codec (zenwebp)
β βββ svg.rs # SVG rasterizer (resvg) + tracer (vtracer)
β βββ avif.rs # AVIF codec (ravif + rav1d, feature-gated)
β βββ jxl.rs # JPEG XL decoder (jxl-oxide, feature-gated)
β βββ dds.rs # DDS decoder (image dds, feature-gated)
β βββ pcx.rs # PCX codec (pcx crate, feature-gated)
β βββ ultrahdr.rs # Ultra HDR stub (feature-gated)
β βββ apng.rs # APNG codec (feature-gated)
β βββ resize.rs # Image resizing with aspect ratio controls
β βββ crop.rs # Image cropping
β βββ transform.rs # Rotation and flip
β βββ filter.rs # Color filters, blur, sharpen, brightness/contrast/gamma
β βββ watermark.rs # Text watermark (imageproc + ab_glyph)
β βββ overlay.rs # Image overlay compositing
β βββ exif.rs # EXIF auto-orient and preservation
β βββ info.rs # Image metadata info output
β βββ compare.rs # SSIM/PSNR comparison (feature-gated)
β βββ dedup.rs # SHA-256 deduplication (feature-gated)
β βββ preset.rs # Conversion presets
β βββ quality.rs # Quality defaults and validation
β βββ animation.rs # GIF frame extract / assemble
β βββ error.rs # ConvertError enum (thiserror)
Input β Format Detection β Decode β [Auto-Orient] β [Crop] β [Resize]
β [Rotate/Flip] β [Filters] β [Brightness/Contrast/Gamma]
β [Blur/Sharpen] β [Watermark] β [Overlay] β Encode β [Preserve EXIF] β Output
# Build
cargo build --release
# Build with all features
cargo build --release --features avif,jxl,dds,pcx,compare,dedup
# Run tests
cargo test
# Run tests with all features
cargo test --features "pcx,compare,dedup"- Base tests: 173 passed
- Full tests (with pcx, compare, dedup): 188 passed
- Property-based tests: 28 included
- Failures: 0
MIT