Last active
November 13, 2021 11:33
-
-
Save radiantly/ac373cc3996963fd46755ab34cae61de to your computer and use it in GitHub Desktop.
A simple script that allows you to scan and trim multiple pages into a pdf straight from the commandline on Linux using utsushi and imagemagick
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import subprocess | |
from pathlib import Path | |
from PIL import Image | |
import rich | |
import sys | |
import tty | |
import termios | |
fd = sys.stdin.fileno() | |
old_settings = termios.tcgetattr(fd) | |
def input_char(): | |
try: | |
tty.setcbreak(sys.stdin) | |
ch = sys.stdin.read(1) | |
except: | |
ch = "q" | |
finally: | |
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) | |
return ch | |
docname = input("Enter the name of the doc (without .pdf): ").removeprefix(".pdf") | |
scannedImage = Path("scanned-0.png") | |
images = [] | |
CLEAR_LINE = "\033[2K\r" | |
def println(*args): | |
print(CLEAR_LINE, flush=True, end="") | |
rich.print(*args, flush=True, end="") | |
println("Press Enter to start scanning page 1: ") | |
while input_char() != "\n": | |
pass | |
scanning = True | |
while scanning: | |
println(f"Scanning page {len(images) + 1} ..") | |
subprocess.run( | |
[ | |
"utsushi", | |
"scan", | |
"--no-interface", | |
"--image-format=PNG", | |
"scanned-%i.png", | |
] | |
) | |
if not scannedImage.exists(): | |
println("Scan failed. Press Enter to try again:") | |
input_char() | |
continue | |
subprocess.run(["convert", "scanned-0.png", "-trim", "-fuzz", "5%", "scanned-0.png"]) | |
println( | |
f"Scan complete. Do you want to\n" | |
+ " [bold yellow]\\[s][/bold yellow] start re-scanning the current page\n" | |
+ " [bold yellow][Enter][/bold yellow] start scanning the next page\n" | |
+ " [bold yellow][Ctrl+C][/bold yellow] save and exit" | |
) | |
while True: | |
choice = input_char() | |
if choice in "sq\n": | |
print("\033[2K\033[1A" * 3, flush=True, end="") | |
if choice == "s": | |
break | |
images.append(Image.open(scannedImage)) | |
println(f"Page {len(images)} added.\n") | |
if choice == "q": | |
scanning = False | |
pdfname = Path(f"{docname}.pdf").absolute() | |
images[0].save( | |
pdfname, | |
"PDF", | |
resolution=100.0, | |
save_all=True, | |
append_images=images[1:], | |
) | |
println(f"\nSaved as {pdfname.as_posix()}\n") | |
break | |
scannedImage.unlink() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment