Film-grade image processing with authentic film stocks, camera profiles, and Hollywood-style color grading.
- π¬ 4 Film Stocks: Kodak Portra, Vision3, Fuji Velvia, Tri-X
- π· Camera Profiles: Fuji X-T4/X-T3, Nikon, Kodak color matrices
- π¨ Professional Effects: Skin protection, highlight rolloff, micro-contrast
- π― 4 Presets: Portrait, Landscape, Street, Blockbuster
- π² Random Generator: Experimental effects for creative exploration
- π Repligen Integration: Auto-process AI-generated images
- β‘ libvips: Hardware-accelerated image processing
# Install dependencies
gem install ruby-vips tty-prompt
# macOS: brew install vips
# Ubuntu: sudo apt install libvips-dev
# OpenBSD: doas pkg_add vips
# Run interactive mode
ruby postpro.rbPerfect for headshots, fashion, beauty:
Effects: skin_protect, film_curve, highlight_roll, micro_contrast, grain
Stock: Kodak Portra (soft, creamy)
Temp: 5200K (warm)Vibrant nature and outdoor scenes:
Effects: film_curve, color_separate, highlight_roll, micro_contrast
Stock: Fuji Velvia (saturated, punchy)
Temp: 5800K (daylight)Gritty documentary, black & white vibe:
Effects: film_curve, shadow_lift, micro_contrast, vintage_lens
Stock: Tri-X (classic B&W)
Temp: 5600K (neutral)Hollywood teal & orange, cinematic look:
Effects: teal_orange, grain, bloom_pro, highlight_roll
Stock: Kodak Vision3 (cinema film)
Temp: 4800K (cool/warm contrast)$ ruby postpro.rb
# Choose workflow
> Masterpiece Presets (Recommended)
# File patterns
> **/*.jpg
# Variations
> 3
# Preset
> portrait
Processing 24 files...
Saved masterpiece 1: photo_portrait_v1_20251010123456.jpg
Saved masterpiece 2: photo_portrait_v2_20251010123458.jpg
Complete! 24 files β 72 masterpieces (18.3s)
Preserves skin tones during aggressive grading:
skin_protect(image, intensity: 0.8)-
Detects skin hue range (25-64Β° in HSV)
-
Reduces saturation adjustments on skin
-
Essential for portrait work
Authentic film response curves:
film_curve(image, stock: :kodak_portra, intensity: 1.0)-
Shadow lift (blacks aren't pure black)
-
Gamma curve (midtone contrast)
-
Highlight rolloff (soft clipping)
Cinematic highlight compression:
highlight_roll(image, threshold: 200, intensity: 0.7)-
Prevents blown highlights
-
Emulates film latitude
-
Creates "glow" in bright areas
Local contrast enhancement:
micro_contrast(image, radius: 5, intensity: 0.3)-
Sharpens without halos
-
Adds "depth" and dimension
-
Mimics medium format clarity
Organic film grain simulation:
grain(image, iso: 400, stock: :kodak_portra, intensity: 0.4)-
Luma-dependent (more in shadows)
-
Matched to film stock characteristics
-
Breaks up digital "perfection"
Hollywood blockbuster color grade:
teal_orange(image, intensity: 1.0)-
Pushes shadows toward teal/cyan
-
Lifts highlights toward orange/amber
-
Protects skin tones automatically
Cinematic bloom and glow:
bloom_pro(image, intensity: 1.0)-
Multi-radius gaussian blur
-
Highlights only
-
Anamorphic lens simulation
Create JSON recipes for repeatable workflows:
{
"skin_protect": 0.8,
"film_curve": {
"intensity": 1.0,
"stock": "kodak_portra"
},
"highlight_roll": 0.7,
"micro_contrast": 0.4,
"grain": 0.3,
"color_temp": {
"kelvin": 5200,
"intensity": 0.6
}
}
Save as recipes/my_portrait.json, then:
$ ruby postpro.rb
> Custom JSON Recipe
> recipes/my_portrait.json
See recipes/ directory for examples.
Auto-detected from EXIF data:
camera_profiles/
βββ fuji.json # X-T4, X-T3 (Classic Chrome simulation)
βββ kodak.json # DCS Pro SLR/c
βββ nikon.json # D850, Z6/Z7Each profile includes:
-
3x3 color matrix (XYZ β sRGB)
-
Saturation boost
-
Vibrance adjustments
-
Optional base tint
Profiles apply before effects for accurate color reproduction.
grain: 15, gamma: 0.65, rolloff: 0.88-
Wedding, fashion, beauty
-
Creamy skin tones
-
Subtle, refined colors
grain: 20, gamma: 0.65, rolloff: 0.85-
Cinema film stock
-
Rich shadows, smooth highlights
-
Wide dynamic range
grain: 8, gamma: 0.75, rolloff: 0.92-
Landscape, nature
-
Hyper-saturated colors
-
Contrasty, punchy
grain: 25, gamma: 0.70, rolloff: 0.80-
Black & white classic
-
Gritty street photography
-
High grain, high contrast
Experimental mode for creative exploration:
> Random Effects (Experimental)
> Professional / Experimental
> 4 effects
Available: grain, leaks, sepia, bloom, teal_orange, cross, vhs, chroma, glitch, flareEach variation gets random:
-
Effect combination
-
Intensity (0.3-1.5)
-
Order of operations
Perfect for discovering unexpected looks!
Postpro auto-detects Repligen-generated images:
$ ruby postpro.rb
Repligen detected! Auto-processing generated images...
Found 8 recent Repligen outputs
Choose preset for Repligen outputs: [portrait, landscape, street, blockbuster]
Looks for *_generated_*.{jpg,png,webp} modified in last 5 minutes.
Set defaults in master.json:
{
"config": {
"multimedia": {
"postpro": {
"apply_camera_profile_first": true,
"default_preset": "portrait",
"variations": 2,
"jpeg_quality": 95
}
}
}
}
-
Bootstrap Module: Auto-installs gems, detects OS, loads config
-
Safe Operations: All functions use
safe_cast()for error handling -
Streaming: Sequential processing with low memory footprint
-
Garbage Collection: Explicit GC every 10 images
-
All outputs preserve EXIF metadata
-
Originals never modified (new files with suffix)
-
File naming:
original_preset_v1_20251010123456.jpg -
Progress logged to
postpro.log -
Requires libvips for performance (100x faster than ImageMagick)
Version: 14.2.0 License: MIT
Dependencies: ruby-vips, tty-prompt (optional)