Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

My scanpdf solution

I have not personally needed to forcibly scan a document, i.e., print one out, just to sign it, and then scan it in again. I have my trusty signatures.pdf that I scanned in a few years ago with 10 iterations of my signature. I always just screenshot a signature, and use LibreOffice Draw's ability to set a transparent color of an imported image.

But, after reading an interesting Hacker News discussion, I have whipped up a "scanpdf" solution. 99% of this is ripped straight from the author, mrb.

Here is my file ~/bin/scanpdf.sh, with typo/semantic fixes.

#!/bin/bash
# from https://news.ycombinator.com/item?id=30024165#30027344
# Make a pdf look like it was scanned.
if [ $# -ne 2 ]; then
   echo "Usage: $0 input output" >&2
   exit 1
fi
tmp="$1".scanner-look.tmp
mkdir "$tmp" &&
# without -flatten some PDF convert to a JPG with a black background
convert -density 150 "$1" -colorspace Gray -quality 60 -alpha flatten "$tmp"/p_in.jpg &&
: || exit 1
# each page is randomly shifted in the X and Y plane.
# units seem to depend on angle of rotation in ScaleRotateTranslate?
offset() { echo $(($RANDOM % 1000)); }
for f in "$tmp"/p_in*jpg; do
   # each page is randomly rotated by [-0.5 .. 0.5[ degrees
   angle=$(python3 -c 'import random; print(random.random()-0.5)')
   x=$(offset)
   y=$(offset)
   convert "$f" \
      -blur 0x0.5 \
        -distort ScaleRotateTranslate "$x,$y $angle" +repage \
      \( +clone +noise Random -fill white -colorize 95% \) \
      -compose darken \
      -composite \
      ${f/p_in/p_out}.pdf || exit 1
done
# concatenate all the pages to one PDF
# use "ls -v" to order files correctly (p_out-X.jpg where X is 0 1 2 ... 9 10 11 ...)
pdftk $(ls -v "$tmp"/p_out*.pdf) cat output "$2" &&
rm -rf "$tmp"

Dependencies include pkdftk(1) and ImageMagick. Also important is to make sure the ImageMagick policy had read and write acess to PDFs. Ensure something similar to this logic is in file /etc/ImageMagick-6/policy.xml.

<policy domain="coder" rights="read | write" pattern="PDF" />

References

Weblinks

  1. FalsiScan: Make it look like a PDF has been hand signed and scanned | Hacker News
  2. Edouard Klein / falsisign | Gitlab
  3. linux - ImageMagick security policy 'PDF' blocking conversion - Stack Overflow

Comments