diff --git a/photobooth.py b/photobooth.py index 49b38d9..4decc1b 100755 --- a/photobooth.py +++ b/photobooth.py @@ -110,8 +110,12 @@ class Config: def convert_to_ascii(jpg_bytes, width, height, flags): + # height=None means "roll printer": only the width is fixed, so let the + # converter derive height from the image's own aspect ratio instead of + # forcing both dimensions and distorting or cropping the art. + dim_flags = ["-W", str(width)] if height is None else ["-d", f"{width},{height}"] proc = subprocess.run( - ["ascii-image-converter", "-", "-d", f"{width},{height}", *flags], + ["ascii-image-converter", "-", *dim_flags, *flags], input=jpg_bytes, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, @@ -206,7 +210,16 @@ def prepare_print_frame(frame, cfg, inner_cols, inner_rows): first and mangling already-rendered ascii text, which doesn't account for non-square character cells and reads as visibly distorted. """ - if cfg.printer_a4: + if cfg.printer_max_lines == 0: + # Roll printer: paper feeds continuously, so there's no page height + # to crop to - only the carriage width (PRINTER_MAX_COLS) limits the + # print. Leave the frame uncropped and pass rows=None downstream so + # ascii-image-converter derives height from the image's own aspect + # ratio instead of forcing a row count. + cols, rows = cfg.printer_max_cols, None + if cfg.printer_a4: + frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE) + elif cfg.printer_a4: cols, rows = cfg.printer_max_cols, cfg.printer_max_lines # Cropping happens before the 90-degree rotation below, which swaps # width and height, so crop to the inverse of the final aspect ratio. @@ -338,7 +351,7 @@ def main(stdscr): ) print_jpg_bytes = print_buf.tobytes() print_width = cfg.width or str(print_cols) - print_height = cfg.height or str(print_rows) + print_height = cfg.height or (str(print_rows) if print_rows is not None else None) print_ascii_lines = convert_to_ascii( print_jpg_bytes, print_width, print_height, conv_flags ) diff --git a/printer.conf b/printer.conf index c5a61d8..861a3a1 100644 --- a/printer.conf +++ b/printer.conf @@ -21,5 +21,12 @@ PRINTER_A4=false # then read off the last line number on page 1 (-> PRINTER_MAX_LINES) and # how many characters of the 64-wide test lines actually printed before # being cut off (-> PRINTER_MAX_COLS). +# +# Set PRINTER_MAX_LINES=0 for a roll/continuous-feed printer that has no +# fixed page length. In that mode photobooth.py sizes captures to fill +# PRINTER_MAX_COLS width 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 instead of skipping the feed when a +# page is already full (there's no page to fill). PRINTER_MAX_LINES=64 PRINTER_MAX_COLS=54 diff --git a/txt2printr.sh b/txt2printr.sh index e168577..478afdd 100755 --- a/txt2printr.sh +++ b/txt2printr.sh @@ -9,7 +9,8 @@ # converting it to ascii (photobooth.py does this # for better quality; set by it automatically) # Reads printer.conf for PRINTER_A4 (landscape rotation) and PRINTER_MAX_LINES -# (per-page line capacity, measured with pagetest.sh). +# (per-page line capacity, measured with pagetest.sh; 0 means a roll/ +# continuous-feed printer with no fixed page length). dir="$(dirname "$0")" [ -f "$dir/printer.conf" ] && source "$dir/printer.conf" @@ -84,7 +85,9 @@ line_count=$(body | wc -l) # Skip the form feed once the page is already full: printers commonly # auto-advance to a new page as soon as content hits the bottom margin, # so an explicit form feed on top of that just ejects a blank extra page. - if [ "$line_count" -lt "$PRINTER_MAX_LINES" ]; then - printf '\x0c' # form feed - eject the page + # A roll printer (PRINTER_MAX_LINES=0) has no page to fill or auto-advance + # past, so always feed the paper out to clear the printed art for tear-off. + if [ "$PRINTER_MAX_LINES" -eq 0 ] || [ "$line_count" -lt "$PRINTER_MAX_LINES" ]; then + printf '\x0c' # form feed - eject the page / advance the roll fi } > "$dev"