Skip to content

Instantly share code, notes, and snippets.

@mludvig
Created April 22, 2011 13:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mludvig/936678 to your computer and use it in GitHub Desktop.
Save mludvig/936678 to your computer and use it in GitHub Desktop.
scan2pdf.sh - Linux command-line scan-to-pdf script
#!/bin/bash -e
## Put your sane-detected device name here.
#DEVICE="snapscan"
## For network scanners use
#DEVICE="net:sane.example.org:snapscan"
DEVICE='brother4:net1;dev0'
## See scanimage --device $(DEVICE) --help
SOURCES[0]="FlatBed"
SOURCES[1]="Automatic Document Feeder(left aligned)"
SOURCES[2]="Automatic Document Feeder(left aligned,Duplex)"
SOURCES[3]="Automatic Document Feeder(centrally aligned)"
SOURCES[4]="Automatic Document Feeder(centrally aligned,Duplex)"
SOURCE=${SOURCES[3]} # Default
RESOLUTIONS=(100 150 200 300 400 600 1200 2400 4800 9600)
RESOLUTION=150 # Default
MODES[0]="Black & White"
MODES[1]="Gray[Error Diffusion]"
MODES[2]="True Gray"
MODES[3]="24bit Color"
MODES[4]="24bit Color[Fast]"
MODE=${MODES[2]} # Default
function process_option()
{
declare -a ARRAY=("${!1}"); shift
VALUE=$1; shift
DEFAULT=$1; shift
MESSAGE=$1; shift
if in_array ARRAY[@] "${VALUE}"; then
echo ${VALUE}
exit 0
fi
if [ ${VALUE} -lt 0 -o ${VALUE} -ge ${#ARRAY[@]} ]; then
echo "$0: ${MESSAGE}"
list_array ARRAY[@] "$DEFAULT"
exit 1
fi >&2
echo ${ARRAY[${VALUE}]}
}
function in_array()
{
declare -a ARRAY=("${!1}"); shift
VALUE=$1; shift
for i in ${!ARRAY[@]}; do
test "${ARRAY[$i]}" = "${VALUE}" && return 0
done
return 1
}
function list_array()
{
declare -a ARRAY=("${!1}"); shift
DEFAULT=$1; shift
for i in ${!ARRAY[@]}; do
MARK_DEFAULT=" "
test "${ARRAY[$i]}" = "${DEFAULT}" && MARK_DEFAULT="*"
echo " ${MARK_DEFAULT} [$i] ${ARRAY[$i]}"
done
}
while getopts m:s:r:d:o:kh OPTION
do
case ${OPTION} in
m)
MODE=$(process_option MODES[@] "${OPTARG}" "${MODE}" "invalid mode, valid values for -m are:")
test $? -gt 0 && exit 1
;;
r|d)
RESOLUTION=$(process_option RESOLUTIONS[@] "${OPTARG}" "${RESOLUTION}" "invalid resolution, valid values for -r are:")
test $? -gt 0 && exit 1
;;
s)
SOURCE=$(process_option SOURCES[@] "${OPTARG}" "${SOURCE}" "invalid source, valid values for -s are:")
test $? -gt 0 && exit 1
;;
o)
OUTFILE=${OPTARG}
;;
k)
KEEP_TMP=1
;;
h|?)
usage
exit 2
esac
done
test -z "${OUTFILE}" && usage
echo -e "\e[1mScanning options:\e[0m"
echo -e "\e[33mMODE: \e[1m${MODE}\e[0m"
echo -e "\e[33mDPI: \e[1m${RESOLUTION}\e[0m"
echo -e "\e[33mSOURCE: \e[1m${SOURCE}\e[0m"
echo -e "\e[33mOUTFILE: \e[1m${OUTFILE}\e[0m"
#SCANIMAGE_OPTS=' --resolution 150 --brightness 20 --contrast 20 -l 0 -t 0 -x 210 -y 290'
SCANIMAGE_OPTS=' -l 0 -t 0 -x 210 -y 290'
if [ "$1" = "" ]; then
echo "Usage: $0 <output-file-name.pdf>"
exit 1
fi
TMPDIR=$(mktemp -d /tmp/scan2pdf.XXXXXXX)
echo "Temporary files kept in: ${TMPDIR}"
cd ${TMPDIR}
set +e
scanimage --device ${DEVICE} ${SCANIMAGE_OPTS} --resolution ${RESOLUTION} --source="${SOURCE}" --mode="${MODE}" --progress --verbose --format=tiff --batch # --batch-prompt
set -e
ls -1 out*.tif > /dev/null
tiffcp -c lzw out*.tif scan.tiff
cd -
tiff2pdf -z ${TMPDIR}/scan.tiff > ${OUTFILE}
ls -l ${OUTFILE}
if [ -z "${KEEP_TMP}" ]; then
rm -rf ${TEMPDIR}
else
echo "Temporary files are in ${TEMPDIR}"
fi
@stevesimmons
Copy link

Lines 129 and 131 should be TMPDIR, not TEMPDIR

@kaovd
Copy link

kaovd commented Jan 9, 2018

Despite being written 7 years ago this script still can be hacked into whatever you need it for. I might go ahead and post a proper working code of this as minor changes need to be made to modern syntax changes in scanimage and the program as I want to be able to save someone a few hours because I run a CUPS node with ssh access and this script is exactly what I need.

@tmaiden
Copy link

tmaiden commented Feb 6, 2018

I might go ahead and post a proper working code of this

NotANormie, please make an updated version of this script. I know, just by looking at it, that I'm going to spend at least an hour tweaking it to my liking; yet in 30 seconds I could/could-of opened simple-scan.

@tmaiden
Copy link

tmaiden commented Feb 6, 2018

Here is where I'm leaving it at. Testing scan resolution vs jpeg quality.

for r in 300 150 75; do scanimage --device "pixma:04A9173A_90265B" -l 0 -t 0 -x 216.069mm -y 253.990mm --source FlatBed --resolution ${r} --mode="Gray" --progress --verbose --format=tiff > "scanimage${r}.tiff"; for q in 100 75 50 25; do tiff2pdf -p letter -j -q ${q} -t "Document" -f -o "tiff2pdf${q}.pdf" "scanimage${r}.tiff"; done; done

@fonic
Copy link

fonic commented Apr 19, 2021

I created an updated and extended version of this script from scratch:
https://gist.github.com/fonic/a9b6920f7a63abe818c541970415b1a0

Big thanks to the author of the original!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment