#!/usr/bin/env bash # HEADER #======================================================================= # # img2copie -- Shell script to generate a PDF from a folder of images # # SYNOPSIS # img2copie # # DESCRIPTION # Shell script to make a PDF file from scanned images of an exam # paper isolated in a directory, for example got with "Open Note Scanner. # By default, the produced PDF file has the same name as the image # folder. # # EXAMPLE # $ img2copie # # POSITIONAL ARGUMENT # directory where the image collection is # # OPTIONS # -h|--help display this help and exit # -g|--gray to convert display as grayscale # [aA][3-5] define output page format # -m|--mode [screen|ebook|printer|prepress] # ghostscript mode, with image resolution as # - screen: 72 DPI # - ebook: 150 DPI # - printer: 300 DPI # - prepress: 300 DPI # -r|--resolution) [num] # compress images with resolution in range # of 72-1200 DPI # -f|--flatten to render transparency to bitmap # -o , --output # output PDF file (single) # # EXAMPLES # $ img2copie photos/ # will produce photos.pdf # $ img2copie photos/ a4 -o copie.pdf # # which is nearly equivalent as: # $ img2pdf -o copie.pdf --pagesize a4 photos/*.png # # DEPENDENCIES # - ghostscript # - imagemagick # - GNU coreutils # # INSTALLATION # - copy file to "/home/$(whoami)/bin" # - make executable with "chmod +x img2copie" # - change permission "none" to "read | write" for PDF in # "/etc/ImageMagick-*/policy.xml" such that: # # # Copyright (C) 2023 Nicolas Mesnier # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 or # above as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #======================================================================= # END_OF_HEADER #----------------------------------------------------------------------- # *** read this header to display help and version #----------------------------------------------------------------------- BOH=$(head -200 ${0} | grep -n "^# HEADER" | cut -f1 -d:) EOH=$(head -200 ${0} | grep -n "^# END_OF_HEADER" | cut -f1 -d:) function Help(){ head -$(($EOH-1)) ${0} | tail -$(($EOH-$BOH-1)) \ | grep -e "^#$" -e "^# " | sed -e "s/^#=*//g" } #======================================================================= # *** get options *** #======================================================================= # default IMG="" PDFFILE="" OPTIONS="" PDFVERSION="1.4" MODE="/printer" RESOLUTION=300 PAPER="a4" while [[ ${1} ]]; do case "${1}" in -h|--help) Help exit 0 ;; -g|--gray) OPTIONS+=" -sColorConversionStrategy=Gray" OPTIONS+=" -dProcessColorModel=/DeviceGray" OPTIONS+=" -dOverrideICC" ;; -m|--mode) case "${2}" in screen|ebook|printer|prepress) MODE="/"${2} ;; *) echo "Mode must be part of {screen|ebook|printer|prepress}." >&2 exit 1;; esac shift ;; -r|--resolution) if [ ${2} -lt 72 -o ${2} -gt 1200 ];then echo "Resolution must be in range 72-1200 DPI." >&2 exit 1 else RESOLUTION=${2} fi OPTIONS+=" -dColorImageDownsampleType=/Bicubic" OPTIONS+=" -dColorImageResolution="${RESOLUTION} OPTIONS+=" -dGrayImageDownsampleType=/Bicubic" OPTIONS+=" -dGrayImageResolution="${RESOLUTION} OPTIONS+=" -dMonoImageDownsampleType=/Bicubic" OPTIONS+=" -dMonoImageResolution="${RESOLUTION} shift ;; a3|A3) PAPER="a3" ;; a4|A4) PAPER="a4" ;; a5|A5) PAPER="a5" ;; -f|--flatten) PDFVERSION="1.3" ;; -o|output) if [ -f ${2} ]; then read -p " File \"${2}\" allready exists. Replace? y/[n] " rep case ${rep} in [Yy]* ) PDFFILE=${2%.pdf}".pdf" ;; * ) exit 1;; esac else PDFFILE=${2%.pdf}".pdf" fi shift ;; *) if [ -d ${1} ];then IMG=${1} else echo "Directory \"${1}\" does not exists." >&2 exit 1 fi ;; esac if ! shift; then echo 'Missing parameter argument.' >&2 exit 1 fi done #----------------------------------------------------------------------- # *** check if their are images #----------------------------------------------------------------------- if [ -z ${IMG} ];then echo "You must give a directory for images." >&2 exit 1 fi if [ "$(wc -l <(ls -l ${IMG}) | cut -d ' ' -f1)" == 0 ];then echo "There must be at leat one image in directory \"${IMG}\"." >&2 exit 1 fi #----------------------------------------------------------------------- # *** output file #----------------------------------------------------------------------- # give image directory by default if [ -z ${PDFFILE} ];then PDFFILE=${IMG}".pdf" fi if [ -f ${PDFFILE} ]; then read -p " File \"${PDFFILE}\" allready exists. Replace? y/[n] " rep case $rep in [Yy]* ) ;; * ) exit 1;; esac fi #----------------------------------------------------------------------- # *** run #----------------------------------------------------------------------- # create temp directory and removed it as script exits. TMPDIR=$(mktemp -d) || exit 1 trap "cd / ; rm -rf '${TMPDIR}'" EXIT # convert all photos to PDF for PHOTO in $(find ${IMG}/ -regextype sed -regex ".*/*\.\(jpe\?g\|JPE\?G\|png\|PNG\)" | sort);do NEWNAME=$(basename "${PHOTO}" | sed "s/\.\(jpe\?g\|JPE\?G\|png\|PNG\)/.pdf/g") convert -background white -page ${PAPER} -compress Zip -quality 0 \ ${PHOTO} ${TMPDIR}/${NEWNAME} done gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dQUIET \ -dCompatibilityLevel=${PDFVERSION} -dPDFSETTINGS=${MODE} \ -dEmbedAllFonts=true -dSubsetFonts=true \ -dAutoRotatePages=/None ${OPTIONS} \ -sPAPERSIZE=${PAPER} -dFIXEDMEDIA -dPDFFitPage \ -sOutputFile=${IMG}.pdf $(ls ${TMPDIR}/*.pdf) #--------------------------------------------------------------------eof