A Swift macOS app and CLI tool for adding professional borders, captions, and texture overlays to photos. Designed for photographers to post-process images exported from Adobe Lightroom with vintage-style borders and EXIF metadata captions.
Note: This project was created using Claude Code as an experiment in AI-assisted development.
The border format is inspired by an old box of photos from my grandfather, featuring white borders with machine-printed dates.
- Photo Library Integration: Browse and select photos from your library
- Live Preview: Real-time preview of border, caption, and overlay settings
- Preset Management: Create, edit, and apply processing presets
- Batch Export: Process multiple images with drag-and-drop
- Batch Processing: Process single images or entire directories
- Concurrent Workers: Multi-core processing with configurable worker count
- Shell Scripting: Integrate into automated workflows
- Solid: Clean, colored border with customizable padding
- Instagram: Fixed 4:5 ratio frame optimized for Instagram posts
- Canvas Layer: Set physical canvas size with width/height
- Border Layer: Configurable thickness, color, and padding
- Orientation Layer: Force landscape or portrait via 90-degree rotation
- Caption Layer: EXIF-based captions with template tokens
- Overlay Layer: Texture overlays (dirt, film dust, light leaks, wet plate) with blend modes
- Dither Layer: 9 dithering algorithms with 3 color modes, pre-processing controls
- Algorithms: Bayer (ordered), Floyd-Steinberg, Atkinson, Blue Noise, Artistic Drip (Parker), Halftone (clustered dot), Stucki, White Noise, Riemersma (Hilbert curve)
- Color Modes: Black & white, two-tone (custom fg/bg colors), full color (per-channel quantization)
- Controls: Threshold (brightness), pixel scale (1–8× chunky retro), Bayer level (1–4), pre-sharpen, contrast
- Quality: Serpentine scanning on all error diffusion, sRGB↔linear gamma conversion
- EXIF Date Extraction: Automatically displays date as "MON 'YY" format
- Custom Templates: Use
{{field}}placeholders for dynamic captions{{camera}},{{lens}},{{iso}},{{aperture}},{{shutter}},{{focal}}{{year}},{{year2}},{{month}},{{mon}},{{day}},{{date}}{{width}},{{height}}(canvas dimensions)
- Font Styling: Bold and italic font style options
- Built-in Presets: Vintage, Instagram, Minimal
- Custom Presets: Save and load YAML-based presets from
~/.config/framer/presets/
Swift Package with three targets:
| Target | Description |
|---|---|
| FramerCore | Image processing library — borders, captions, overlays, presets |
| FramerCLI | Command-line interface using Swift Argument Parser |
| FramerApp | SwiftUI macOS application |
Dependencies:
- swift-argument-parser — CLI argument parsing
- Yams — YAML preset/config parsing
Requires Swift 5.10+ and macOS 14+.
# Clone repository
git clone https://github.com/arthursoares/framer.git
cd framer
# Build CLI
swift build
# Run CLI
swift run framer -i photo.jpg -o output/
# Run tests
swift test# Generate Xcode project (requires xcodegen)
xcodegen generate
# Open and build in Xcode
open Framer.xcodeproj# Process a single image
framer -i photo.jpg -o output/
# Process a folder
framer -i photos/ -o output/
# Use a preset
framer -i photo.jpg -o output/ --preset vintage
# Custom caption template
framer -i photo.jpg -o output/ --caption-template "{{camera}} {{aperture}} {{shutter}}"
# Bold italic caption
framer -i photo.jpg -o output/ --font-bold --font-italic
# Instagram format
framer -i photo.jpg -o output/ -s instagram
# Process with 8 workers
framer -i photos/ -o output/ --workers 8# Build
swift build
# Test
swift test
# Regenerate Xcode project
xcodegen generateThis project is licensed under the MIT License - see the LICENSE file for details.
- Built with Claude Code
- Inspired by vintage photo printing techniques
- Texture overlays from analog film scanning artifacts