diff --git a/readme.md b/readme.md index e69de29..860b560 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,106 @@ +# ASCII Photobooth + +A Linux webcam photobooth that converts live frames to ASCII art in the +terminal, and can optionally send captures to a parallel-port needle/dot-matrix +printer. + +There are two front ends: + +- **`photobooth.py`** — a curses TUI. Grabs frames directly via OpenCV/v4l2 + (no per-frame process spawn), converts them with the `ascii-image-converter` + binary, and supports live brightness/exposure adjustment. This is the + actively developed front end. +- **`exec-cycle.sh` / `webcam2ascii.sh`** — a simpler bash implementation of + the same live-preview loop, built around `fswebcam` and `ascii-image-converter`. + +Both read the same `webcam.conf` / `ascii.conf` / `keybinds.conf` / +`printer.conf` files, so you only need to configure your hardware once. + +## Requirements + +- Arch Linux (or another `pacman`/AUR-based distro) is assumed by + `install-deps.sh` +- `fswebcam`, `ascii-image-converter`, `v4l-utils` +- `python-opencv` (for `photobooth.py`) +- A V4L2-compatible webcam +- Optionally, a parallel-port printer wired up via `parport`/`parport_pc`/`lp` + kernel modules, for hardcopy prints + +Install everything with: + +```sh +./install-deps.sh +``` + +This installs [`yay`](https://aur.archlinux.org/packages/yay) if needed, +installs the required packages, adds your user to the `lp` group (needed to +write to `/dev/lp0`), and loads the parallel-port kernel modules. + +## Usage + +Run the TUI (recommended): + +```sh +./photobooth.py +``` + +Or the bash live-preview loop: + +```sh +./exec-cycle.sh +``` + +### Controls + +Configurable in `keybinds.conf`; defaults shown below. + +| Key | Action | +| --- | --- | +| `space` | Capture a photo | +| `+` / `-` | Adjust brightness | +| `.` / `,` | Adjust exposure | +| `r` | Reset brightness/exposure to defaults | +| `q` | Quit (`photobooth.py` only; `exec-cycle.sh` quits on Ctrl+C) | + +Captures are saved as `photo-.jpg` and +`ascii-img-.txt`, and are automatically sent to the printer via +`txt2printr.sh` if one is configured. + +## Configuration + +| File | Purpose | +| --- | --- | +| `webcam.conf` | Capture device, resolution, JPEG quality, default brightness/exposure, and the v4l2 control names/IDs used to adjust them | +| `ascii.conf` | `ascii-image-converter` options: output size, character map/complexity, grayscale, negative, flips, and whether the live-preview viewfinder mirrors the print output's aspect ratio (`REAL_VIEWFINDER`) | +| `keybinds.conf` | Single-character key bindings for capture/brightness/exposure/reset/quit | +| `printer.conf` | Printer device, A4 landscape rotation (`PRINTER_A4`), and per-page capacity (`PRINTER_MAX_LINES`/`PRINTER_MAX_COLS`) | + +### Printing + +`txt2printr.sh` sends an ASCII art text file to a parallel-port printer +(`/dev/lp0` by default, override with `PRINTER_DEV`). Needle/dot-matrix +printers have no hardware landscape mode, so setting `PRINTER_A4=true` in +`printer.conf` rotates the art in software before printing (turn the printed +page 90° to read it); `photobooth.py` instead rotates the source image before +ASCII conversion for better quality, and sets `PRINTER_MAX_LINES=0` to signal +a roll/continuous-feed printer with no fixed page length. + +Printer page capacity varies by hardware and isn't reliably predictable from +paper geometry — measure it with `pagetest.sh`: + +```sh +./pagetest.sh # numbered lines, to find lines-per-page +./pagetest.sh ruler # a column ruler, to find chars-per-line +PRINTER_A4=false ./txt2printr.sh pagetest.txt +``` + +Read the last line/column that printed on page 1 and set +`PRINTER_MAX_LINES`/`PRINTER_MAX_COLS` in `printer.conf` accordingly. +`printer.conf.hpold.bak` and `printer.conf.rollpaper.bak` are example configs +for a couple of previously-tested printers. + +## Other scripts + +- `yay-installer.sh` — installs the `yay` AUR helper (used by `install-deps.sh`) +- `archbaseos-guided-install.sh` — an interactive Arch Linux base install + script (LUKS2/btrfs/FIDO2), unrelated to the photobooth itself