Splits install-deps.sh into per-distro scripts (install_deps_arch.sh,
install_deps_debian.sh, install_deps_fedora.sh) since package names and
managers differ; ascii-image-converter is built via go install on
Debian/Fedora since it's AUR-only on Arch.
Sizes the curses viewfinder box to match the print output's character
grid (A4/roll-paper target dims) instead of always filling the
terminal, and always centers the box. Defaults to true.
A continuous-feed printer has no fixed page length, so photobooth.py
now sizes captures to the carriage width (PRINTER_MAX_COLS) and lets
height follow the image's own aspect ratio instead of cropping to a
row count, and txt2printr.sh always feeds the paper out at the end of
a print since there's no page to auto-advance past.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rearranging already-rendered ascii characters (the old text-transpose
rotation) ignores non-square character cells and read as visibly
distorted. Instead, crop the raw camera frame to roughly the right
aspect ratio, rotate it (only for PRINTER_A4) with OpenCV, and only
then convert to ascii - so ascii-image-converter picks shading
characters for correctly-oriented pixel data instead of us hacking
around after the fact.
The live curses viewfinder is now a separate, always-upright,
aspect-corrected preview independent of PRINTER_A4; the rotated/resized
version used for printing is computed fresh from the raw frame only at
capture time.
txt2printr.sh gains ALREADY_ROTATED, set automatically by photobooth.py
so it doesn't redundantly apply its own text-rotation on top of the
image-level one. The bash pipeline (webcam2ascii.sh/exec-cycle.sh),
which can't rotate images itself, still falls back to that text
rotation unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Repeating-digit and prefixed-number test lines make it hard to read
off exactly where a printer truncates a line. `./pagetest.sh ruler`
prints a single line marking every 10th column with its tens digit
and every 5th with '+', so the real cutoff column can be read directly
off the page instead of estimated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Real-world testing (pagetest.sh) showed the printer's actual per-page
line/column capacity didn't match what the A4-geometry math predicted,
and the redundant blank second page was traced to the printer
auto-advancing to a new page once content hits the bottom margin,
with our own unconditional trailing form-feed then ejecting that
already-started blank page on top of it.
Replace PRINTER_CPI/PRINTER_LPI with directly-measured
PRINTER_MAX_LINES/PRINTER_MAX_COLS in printer.conf (read via
pagetest.sh), and have txt2printr.sh skip the trailing form-feed
whenever the print job already reaches that line capacity.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Numbered, fixed-width lines let us read a printer's actual page length
and line width limits straight off the paper, instead of guessing them
from A4 geometry - needed to nail down the real constants for the
PRINTER_A4 landscape math.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
a4_landscape_chars() was sizing the capture/preview to the *final*
landscape look (assuming the physical page gets fed sideways), but
txt2printr.sh actually rotates the ascii art 90 degrees in software on
a normally-fed page. Combining both produced ~107 printed lines,
overflowing the printer's page-length capacity onto a second sheet.
Since the software rotation is cancelled out by the reader turning the
finished page 90 degrees, the capture buffer's own dimensions equal
the final visual result, but its width becomes the printed line count
post-rotation - so it must be capped by the page's line capacity along
the long edge, with height derived from the target landscape aspect
ratio (corrected for non-square character cells) instead of just
filling the available character budget.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Dot-matrix printers have no hardware page-rotation, so when PRINTER_A4
is enabled in the new printer.conf, txt2printr.sh rotates the ascii art
90 degrees in software before sending it, and photobooth.py caps its
live-preview viewfinder to an A4-landscape character grid (sized from
configurable PRINTER_CPI/PRINTER_LPI) instead of just filling the
terminal, so the preview matches what actually gets printed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Missing '!' meant the kernel couldn't recognize the interpreter
directive, causing ENOEXEC (errno 8) when executed directly, e.g.
via subprocess.run() from photobooth.py.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-f only matches regular files, so it never matched the /dev/lp0 or
/dev/usb/lp0 character device nodes, leaving dev unset and always
failing. Use -e existence checks in proper if/elif priority order
(lp0 > usb/lp0 > stdout), with PRINTER_DEV as an unconditional override.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaces per-frame fswebcam process spawns with a persistent OpenCV/v4l2
capture handle for the highest achievable refresh rate, while still
shelling out to ascii-image-converter for conversion and txt2printr.sh
for printing. Renders a bordered live preview with a status/keybind-help
bar via curses, works on a plain TTY with no graphical environment.
Reuses webcam.conf/ascii.conf/keybinds.conf, parsed as plain key=value
(not sourced, so a config file can no longer execute arbitrary code).
Brightness/exposure now go through v4l2-ctl with percentage mapped onto
each control's actual min/max range; added DEVICE/BRIGHTNESS_CTRL_ID/
EXPOSURE_CTRL_ID to webcam.conf and KEY_QUIT to keybinds.conf for this,
kept separate from the bash-oriented keys so the existing bash scripts
are unaffected. Bash scripts are left in place as a fallback.
New deps: python-opencv, v4l-utils.
ascii.conf exposes ascii-image-converter's dimension/complexity/map/
grayscale/negative/flip options (color and braille stay out since they
rely on ANSI/multi-byte Unicode that txt2printr.sh's raw print path
can't render). keybinds.conf lets exec-cycle.sh's capture/brightness/
exposure/reset keys be rebound instead of hardcoded, matched
case-insensitively; the on-screen hint bar renders from the same
config so it never drifts out of sync with the actual bindings.
exec-cycle.sh's live preview now shows brightness/exposure and lets
+/-, ./, adjust them per-frame via fswebcam --set, with r to reset;
webcam.conf centralizes the starting values, step size, capture
resolution/quality, and the v4l2 control names (which vary by camera)
so hardware-specific tuning doesn't require editing the scripts.
txt2printr.sh writes directly to /dev/lp0, which needs the lp kernel
driver loaded (via parport/parport_pc) and lp group membership for
non-root write access; wire both up during dependency install.
writes raw bytes to /dev/lp0 (overridable via PRINTER_DEV): resets the
printer with ESC @, converts LF to CRLF to avoid staircasing on raw
device writes, then form-feeds to eject the page.
replaced the guvcview+keypress capture flow with a continuous
capture/convert/display loop so the terminal shows a live ascii
preview; pressing c saves the frame and triggers the new
txt2printr.sh hook (currently a blank template).