A modern, professional-grade image processing command-line tool built with Python. imgm brings the power of ImageMagick, GIMP, and Photoshop to your terminal.
- CLI Parser - Powerful argparse-based command interface
- Processing Engine - Fast image manipulation with Pillow
- Filter Pipeline - Chain multiple effects together
- Batch Processing - Process entire folders
- Format Conversion - Convert between any image format
- Safe File Handling - No destructive overwrites, proper error handling
- Greyscale - Convert to black & white
- Opacity - Adjust transparency (0.0-1.0)
- Blur - Gaussian blur with adjustable radius
- Resize - High-quality LANCZOS resampling
- Rotate - Rotate images without cropping
- Invert - Invert RGB while preserving alpha
- Brightness - Adjust image brightness (0.0-2.0)
- Contrast - Adjust image contrast (0.0-2.0)
- Multithreading - Process multiple images in parallel (
--threads N) - Progress Bars - Visual feedback with tqdm
- Colorized Output - Rich, color-coded terminal output
- Preset System - Pre-built filter combinations for common effects
- Plugin Architecture - Extend with custom filters
- GUI Mode - Simple Tkinter interface for visual editing
cd imgm
pip install -r requirements.txt
pip install -e .Or simply run:
python imgm.py --help# Increase brightness
python imgm.py photo.png --brightness 1.5
# Add blur
python imgm.py photo.png --blur 5 --output photo_blurred.png
# Greyscale
python imgm.py photo.png --greyscale
# Multiple filters at once
python imgm.py photo.png --brightness 1.2 --contrast 1.3 --blur 2# Instagram-style filter
python imgm.py photo.png --preset instagram
# Film noir effect
python imgm.py photo.png --preset noir
# Vintage look
python imgm.py photo.png --preset vintage
# List all presets
python imgm.py --list-presets# Process entire folder with 4 threads
python imgm.py photos/ --brightness 1.1 --batch
# Process with custom thread count
python imgm.py photos/ --blur 3 --batch --threads 8
# Save to different folder
python imgm.py photos/ --preset vivid --batch --output-folder processed/# Convert PNG to JPEG
python imgm.py photo.png --convert jpg --output photo.jpg
# Convert entire folder to WebP
python imgm.py photos/ --convert webp --batch# Launch interactive GUI
python imgm.py --guiThe GUI provides:
- File picker for loading images
- Real-time preview
- Interactive sliders for brightness, contrast, blur
- Preset buttons
- Save functionality
# Resize + apply Instagram preset
python imgm.py photo.png --resize 1920 1080 --preset instagram
# Create noir thumbnail
python imgm.py photo.png --resize 200 200 --preset noir --output thumb.png
# Batch: Greyscale + high contrast
python imgm.py old_photos/ --greyscale --contrast 1.5 --batch
# Process with custom output folder
python imgm.py photos/ --preset bright --batch --output-folder brightened/| Preset | Effect |
|---|---|
instagram |
Bright, high-contrast with slight blur |
noir |
Black & white, high contrast, darker |
vintage |
Slightly desaturated, soft appearance |
bright |
Increased brightness and contrast |
dark |
Darker with enhanced contrast |
vivid |
Enhanced colors and brightness |
Create custom filters and load them automatically on startup.
The --load flag registers a plugin to auto-load on every startup by saving it to plugins.json:
# Register a plugin (saved to plugins.json)
python imgm.py --load ./my_custom_filter.py
# Now the plugin auto-loads on every startup - no need to specify it again
python imgm.py photo.png --brightness 1.2-
First run:
imgm --load ./custom_pixelate.py
- Validates the plugin
- Saves the path to
plugins.json - Returns to prompt
-
Subsequent runs:
imgm photo.png
- Automatically loads plugins listed in
plugins.json - Your registered plugins are ready to use
- No need to specify
--loadagain
- Automatically loads plugins listed in
Create my_custom_filter.py or plugins/my_filter.py:
"""My custom image filter."""
from PIL import Image
def apply_filter(img, **kwargs):
"""Apply custom filter to image.
Args:
img: PIL Image object (RGBA mode)
**kwargs: Optional parameters
Returns:
Modified PIL Image object
"""
# Your filter logic here
if img.mode != 'RGBA':
img = img.convert('RGBA')
# Process the image
# ... your code ...
return img
# Optional: Plugin metadata
plugin_info = {
'name': 'My Filter',
'version': '1.0',
'description': 'My custom image filter',
'author': 'Your Name',
}Option 1: Registered Plugins (Persistent)
# Register once
imgm --load /path/to/my_filter.py
# Auto-loads on every startup
imgm photo.pngOption 2: Folder Plugins (No Registration)
# Drop file in plugins/ folder
cp my_filter.py plugins/
# Auto-discovered on startup
imgm --list-plugins# Shows both registered (persistent) and folder plugins
imgm --list-pluginsStores registered plugin paths:
{
"plugins": [
"/absolute/path/to/pixelate.py",
"/absolute/path/to/custom_sepia.py"
]
}- Created automatically when you use
--load - Stores absolute paths to registered plugins
- Updated on startup
- Can be edited or deleted to reset
The IMGM_CONFIG dictionary in imgm.py defines all CLI flags and arguments. It's organized as:
IMGM_CONFIG = {
'flags': {
'gui': {'help': '...', 'action': 'store_true'},
'batch': {...},
# ... more flags
},
'arguments': {
'input': {'nargs': '?', 'help': '...'},
'output': {...},
'load': {'help': 'Load external plugin from file path'},
# ... more arguments
}
}This centralized configuration makes it easy to:
- Add new CLI flags and arguments
- Maintain consistent help text
- Modify argument types and defaults
positional arguments:
input Input image or folder
optional arguments:
-o, --output OUTPUT Output file path
-of, --output-folder FOLDER Output folder for batch processing
Filters:
--brightness FACTOR Brightness (0.0-2.0)
--contrast FACTOR Contrast (0.0-2.0)
--blur RADIUS Blur radius (pixels)
--resize WIDTH HEIGHT Resize to dimensions
--rotate DEGREES Rotate (degrees)
--opacity LEVEL Opacity (0.0-1.0)
--greyscale Convert to greyscale
--invert Invert colors
Presets & Plugins:
--preset NAME Apply preset
--list-presets List all presets
--list-plugins List plugins
--load PATH Load external plugin from file path
Conversion:
--convert FORMAT Convert format (png, jpg, gif, etc.)
Batch:
--batch Process entire folder
--threads N Number of threads (default: 4)
GUI:
--gui Launch GUI mode
Other:
-v, --verbose Verbose output
-h, --help Show this help message
- Single file: ~200-500ms
- 100 images (single-threaded): ~30-50s
- 100 images (4 threads): ~12-15s
- 100 images (8 threads): ~8-10s
Performance depends on:
- Image resolution
- Filter complexity
- System CPU cores
- Disk I/O speed
- Use
--threads 4for most systems - Increase for high-core CPUs
- Reduce for low-memory systems
- Process to SSD for faster I/O
imgm never overwrites input files:
- Single files: Saves as
{name}_processed.{ext} - Batch mode: Saves to separate folder
- Use
-o/-ofto specify output location - Supports safe format conversion
imgm/
├── imgm.py # Main CLI entry point
├── processor.py # Core image processing engine
├── filters.py # Filter implementations
├── presets.py # Preset definitions
├── plugins_system.py # Plugin loader
├── gui.py # Tkinter GUI
├── plugins/ # User plugins folder
├── requirements.txt # Dependencies
└── setup.py # Installation script
- Python 3.8+
- Pillow (Image processing)
- tqdm (Progress bars)
- rich (Colorized output)
- colorama (Cross-platform colors)
- tkinter (GUI - usually included with Python)
MIT License - Free for personal and commercial use
Built with ❤️ for image enthusiasts, photographers, designers, and developers.