#!/bin/bash ################# # PREREQUISITES # ################# # executables in PATH for prereq in "python3" "gs" "pdftk"; do if ! command -v "${prereq}" &> /dev/null; then echo "required executable '${prereq}' not found!" exit 1 fi done # python virtual env with PyMuPDF VENV_DIR="pdfsign.venv" if [ -d "${VENV_DIR}" ]; then # venv exists, activate it source "${VENV_DIR}/bin/activate" else for prereq in "venv"; do if ! python3 -c "import ${prereq}" &> /dev/null; then echo "python module '${prereq}' not found!" exit 1 fi done # create venv and activate python3 -m "venv" "${VENV_DIR}" source "${VENV_DIR}/bin/activate" # install PyMuPDF python3 -m "pip" install PyMuPDF fi ############ # CLI ARGS # ############ if [ $# -lt 2 ]; then echo "Usage: ${0} [PAGE]" echo echo "Replaces page PAGE with the signed version." echo "If PAGE is not given, the last page is replaced." exit 1 fi IN_TEXT_PDF="${1}" IN_SCAN_IMG="${2}" OUT_PDF="${IN_TEXT_PDF%%.*}_pdfsign.pdf" IN_TEXT_PDF_LEN="$( pdftk "${IN_TEXT_PDF}" dump_data | grep NumberOfPages | awk '{print $2}' )" IN_PAGE="${3:-${IN_TEXT_PDF_LEN}}" RANGES="B1" if [ ${IN_PAGE} -gt 1 ]; then RANGES="A1-$(( IN_PAGE - 1 )) ${RANGES}" fi if [ ${IN_PAGE} -lt ${IN_TEXT_PDF_LEN} ]; then RANGES="${RANGES} A$(( IN_PAGE + 1 ))-${IN_TEXT_PDF_LEN}" fi ################ # MAIN PROGRAM # ################ GSFLAGS="-sDEVICE=pdfwrite -dSAFER -dNOPAUSE -dQUIET -dBATCH" set -e # extract IN_PAGE (text-only) from IN_TEXT_PDF gs ${GSFLAGS} \ -dFirstPage="${IN_PAGE}" -dLastPage="${IN_PAGE}" \ -dFILTERIMAGE -dFILTERVECTOR -dFILTERTEXT=false \ -sOutputFile=".pdfsign_textonly.pdf" \ "${IN_TEXT_PDF}" # use IN_SCAN_IMG as background, layering text from extracted page on top python3 ./pdfsign.py \ ".pdfsign_textonly.pdf" "${IN_SCAN_IMG}" \ ".pdfsign_signed.pdf" rm ".pdfsign_textonly.pdf" # replace IN_PAGE in IN_TEXT_PDF layered page pdftk A="${IN_TEXT_PDF}" B=".pdfsign_signed.pdf" \ cat ${RANGES} \ output ".pdfsign_concat.pdf" rm ".pdfsign_signed.pdf" # postprocess/compress pdf gs ${GSFLAGS} \ -sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage \ -dCompatibilityLevel=1.7 -dPDFSETTINGS=/ebook \ -sOutputFile="${OUT_PDF}" \ ".pdfsign_concat.pdf" rm ".pdfsign_concat.pdf"