# ESP32 PhotoFrame CLI Node.js CLI tool for processing images for ESP32 PhotoFrame. Uses the [epaper-image-convert](https://github.com/aitjcize/epaper-image-convert) library for advanced image processing pipeline for epaper displays. ## Features - Advanced image processing pipeline with [epaper-image-convert](https://github.com/aitjcize/epaper-image-convert) - Batch folder processing with automatic album organization - Device parameter sync and direct upload - Image server mode for HTTP-based serving ## Installation ### From source (recommended) ```bash git clone https://github.com/aitjcize/esp32-photoframe.git cd esp32-photoframe/esp32-photoframe/process-cli npm install npm link # Makes photoframe-process command available globally ``` After installation, the `photoframe-process` command will be available globally. **System Requirements:** - Node.js 14+ up to Node.js 20 (dependencies are no longer supported for higher versions) - macOS/Linux: Install Cairo dependencies (see below) **macOS:** ```bash brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman ``` **Linux (Ubuntu/Debian):** ```bash sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev ``` ## Usage > **Note:** If installed globally via npm, use `photoframe-process` command. If running from source, use `node cli.js`. ### Single File Processing ```bash # Basic usage photoframe-process input.jpg # With output directory photoframe-process input.jpg -o /path/to/output # Custom parameters photoframe-process input.jpg --scurve-strength 0.8 --saturation 1.5 ``` ### Folder Processing ```bash # Process entire album directory photoframe-process ~/Photos/Albums -o output/ ``` Automatically processes subdirectories as albums, preserving folder structure. ### Device Parameters ```bash # Fetch settings and palette from device photoframe-process input.jpg --device-parameters photoframe-process ~/Photos/Albums --device-parameters -o output/ photoframe-process input.jpg --device-parameters --host 192.168.1.100 ``` ### Direct Upload ```bash # Upload to device (no disk output) photoframe-process input.jpg --upload --host photoframe.local photoframe-process ~/Photos/Albums --upload --device-parameters --host photoframe.local ``` Processes in temp directory, uploads via HTTP API, auto-cleans up. ### Image Server Mode ```bash # Serve images over HTTP (no SD card needed) photoframe-process --serve ~/Photos/Albums --serve-port 9000 --device-parameters --host photoframe.local # Different formats: epdgz (default, fastest), png, bmp, jpg photoframe-process --serve ~/Photos --serve-port 9000 --serve-format epdgz ``` Serves random images on each request. Configure ESP32: **Rotation Mode** → URL, **Image URL** → `http://your-ip:9000/image` ## Options ``` Usage: photoframe-process [options] Arguments: input Input image file or directory with album subdirectories Options: -V, --version output the version number -o, --output-dir Output directory (default: ".") --suffix Suffix to add to output filename (single file mode only) (default: "") --format Output format: epdgz, png, or bmp (default: "epdgz") --upload Upload converted image and thumbnail to device (requires --host) --direct Display image directly on device without saving (requires --host, single file only) --serve Start HTTP server to serve images from album directory structure --serve-port Port for HTTP server in --serve mode (default: "8080") --serve-format Image format to serve: epdgz, png, jpg, or bmp (default: "epdgz") --host Device hostname or IP address (default: "photoframe.local") --device-parameters Fetch processing parameters from device --exposure Exposure multiplier (0.5-2.0, 1.0=normal) (default: 1) --saturation Saturation multiplier (0.5-2.0, 1.0=normal) (default: 1.3) --tone-mode Tone mapping mode: scurve or contrast (default: "scurve") --contrast Contrast multiplier for simple mode (0.5-2.0, 1.0=normal) (default: 1) --scurve-strength S-curve overall strength (0.0-1.0) (default: 0.9) --scurve-shadow S-curve shadow boost (0.0-1.0) (default: 0) --scurve-highlight S-curve highlight compress (0.5-5.0) (default: 1.5) --scurve-midpoint S-curve midpoint (0.3-0.7) (default: 0.5) --color-method Color matching: rgb or lab (default: "rgb") --use-perceived-output Use perceived (measured) palette colors in output for realistic preview --processing-mode Processing algorithm: enhanced (with tone mapping) or stock (Waveshare original) (default: "enhanced") -h, --help display help for command ``` ## Output Files - `photo.epdgz` - Compressed 4-bit-per-pixel display-ready format (default, smallest and fastest) - `photo.png` - 800x480 dithered PNG (theoretical palette for device) - `photo.bmp` - 800x480 dithered BMP - `photo.jpg` - 400x240 thumbnail - `--use-perceived-output` - Use perceived palette colors (realistic preview) ## Processing Pipeline 1. Load image → 2. EXIF orientation → 3. Rotate if portrait → 4. Resize to 800x480 (cover mode) → 5. Tone mapping (S-curve/contrast) → 6. Saturation adjustment → 7. Floyd-Steinberg dithering → 8. Output EPDGZ + thumbnail ## Examples ```bash # Basic processing photoframe-process photo.jpg -o output/ # With device parameters (recommended) photoframe-process photo.jpg --device-parameters -o output/ # Batch folder upload photoframe-process ~/Photos/Albums --upload --device-parameters --host photoframe.local # Custom tone mapping photoframe-process photo.jpg --scurve-strength 1.0 --saturation 1.5 -o output/ # Preview mode (darker, matches e-paper) photoframe-process photo.jpg --use-perceived-output -o preview/ ``` ## Publishing to npm To publish this package to npm (maintainers only): ```bash cd process-cli # Login to npm (first time only) npm login # Publish the package npm publish # For updates, bump version first npm version patch # or minor, or major npm publish ``` ## Development ```bash # Run tests npm test # Run specific test npm run test:orientation # Link for local development npm link photoframe-process input.jpg # Test global command ```