Crunch is a lossy PNG image optimization tool that combines two compression techniques: pngquant (lossy color reduction) and zopflipng (zopfli DEFLATE compression). The project provides three user interfaces: a command-line executable, a native macOS GUI application, and a macOS Finder right-click service.
┌─────────────────────────────────────────────────────────────────┐
│ Crunch Project │
├─────────────────────────────────────────────────────────────────┤
│ User Interfaces │
│ ┌─────────────────┐ ┌──────────────────┐ ┌───────────────┐ │
│ │ CLI Executable │ │ macOS GUI App │ │ macOS Service │ │
│ │ (crunch) │ │ (Platypus) │ │ (Workflow) │ │
│ └────────┬────────┘ └────────┬─────────┘ └───────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ crunch.py (Core Optimization Engine) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌────────────────┐ │ │
│ │ │ ImageFile │ │ optimize_ │ │ multiprocessing│ │ │
│ │ │ Class │ │ png() │ │ Pool │ │ │
│ │ └─────────────┘ └─────────────┘ └────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────┴────────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ pngquant │ │ zopflipng │ │
│ │ (Lossy Stage) │──────────────│ (Compression) │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
crunch.py - The central Python module that handles:
- Argument parsing and validation - CLI argument handling, PNG file validation
- Image processing pipeline - Two-stage optimization (pngquant → zopflipng)
- Parallel processing - Uses Python's
multiprocessing.Poolfor batch optimization - Logging - File-based logging for GUI and service modes
Key classes and functions:
ImageFile- Represents a PNG file with pre/post optimization paths and sizesoptimize_png()- Main optimization function that chains pngquant and zopflipngis_valid_png()- Validates PNG file signaturesget_pngquant_path()/get_zopflipng_path()- Resolves dependency paths based on execution context
Original PNG → pngquant (lossy) → zopflipng (deflate) → Optimized PNG
│
▼
Quality: 80-98
--skip-if-larger
--force --strip
--speed 1
pngquant stage:
- Reduces color palette to 256 colors max
- Quality range: 80-98 (min-max)
- Skips if result is larger than original
- Strips metadata
- Uses speed level 1 (best compression)
zopflipng stage:
- Applies zopfli DEFLATE compression
- Uses filter=0 for quantized files
- Uses lossy_transparent for non-quantized files
- Python script installed to
/usr/local/bin/crunch - Dependencies: pngquant at
~/.local/bin/pngquant, zopflipng at~/.local/bin/zopflipng - Supports parallel processing with automatic CPU core detection
The Crunch macOS GUI application is created using Platypus, a macOS app wrapper that creates native applications from scripts. The application is configured via the Crunch.platypus profile file located in the profile/ directory.
Platypus Configuration:
- Bundle Identifier:
com.akatquas.Crunch - Interface Type: Web View (HTML-based UI)
- Script Path:
src/crunch-gui.sh(executed via/bin/sh) - Icon:
img/CrunchIcon.icns - Remains Running: Yes (waits for dropped files)
- Droppable: Yes (accepts dropped PNG files)
- Accepts Files: Yes
- Right-click "Crunch Image(s)" service
- Processes selected PNG files from Finder
- Installed as
~/Library/Services/Crunch Image(s).workflow
Makefile targets:
build-dependencies- Compiles pngquant and zopflipng from sourceinstall-executable- Installs CLI to/usr/local/bininstall-macos-service- Installs Finder servicebuild-macos-icns- Builds macOS icon setbuild-macos-installer- Creates DMG installer from existingCrunch.app(requirescreate-dmg)test- Runs Python tests, shellcheck, and PNG validation
Build Workflow:
- Create Crunch.app: Use Platypus to load
profile/Crunch.platypusand generate the app - Build icon set (optional):
make build-macos-icns - Create DMG installer:
make build-macos-installer(requiresCrunch.appinbin/directory)
Note: The
create-dmgtool is required to build the DMG installer:
- For local development (
make build-macos-installer): use https://github.com/sindresorhus/create-dmg- For distribution builds (
make dist): use https://github.com/create-dmg/create-dmg
The Crunch.platypus profile defines how Platypus packages the application. When built, it creates:
Crunch.app/
├── Contents/
│ ├── Info.plist # Generated from Platypus profile
│ ├── MacOS/
│ │ └── ScriptExec # Platypus executable (/usr/local/share/platypus/ScriptExec)
│ ├── Resources/
│ │ ├── crunch-gui.sh # Main script (defined in ScriptPath)
│ │ ├── crunch.py # Python engine
│ │ ├── pngquant # Bundled binary dependency
│ │ ├── zopflipng # Bundled binary dependency
│ │ ├── *.html # GUI templates
│ │ ├── animations/ # GIF animations
│ │ └── Credits.html
│ └── PkgInfo
The Crunch.platypus profile file is the configuration source that defines this structure, including:
- All bundled files (pngquant, zopflipng, HTML, icons, animations)
- Interpreter path (
/bin/sh) for script execution - Droppable file types (
public.item,public.folder) - Status item configuration for menu bar integration
The application detects execution context to resolve dependency paths:
| Context | pngquant Path | zopflipng Path |
|---|---|---|
| CLI | ~/.local/bin/pngquant |
~/.local/bin/zopflipng |
| GUI | ./pngquant (relative) |
./zopflipng (relative) |
| Service | /Applications/Crunch.app/Contents/Resources/pngquant |
Full path to app bundle |
- Continuous Integration - GitHub Actions for Linux and macOS
- Testing - Python unit tests with error and execution scenarios (via tox)
- Linting - black for Python, shellcheck for shell scripts
- Validation - pngcheck for PNG output validation
- Benchmarking - Automated comparison against reference images using DSSIM