BASH script to photocopy a page and scan to a PDF

I have been using an Epson TX110 for all of my at home printing needs for about three years. While its scanning function is good, I am absolutely sick of the way I need to keep on replacing colour cartridges even though I only ever print in black and white. My colour usage has, in fact, almost entirely been taken up by routing cleaning of the printer heads.

So, rather then spend another dollar on colour cartridges I will never use, I finally bit the bullet and purchased a laser printer.

Being a linux-geek, the first thing I did was connect it to my home server and share it with my laptop and desktop.

The next thing I wanted was the ability to link the scanner function on the Epson TX110 with the Brother laser printer, to be able to quickly photocopy a page. This is amazingly easy with bash and the right tools installed:-

#! /bin/bash
#Find the default printer, or set printer with a literal string e.g. PRINTER="HL2140"
PRINTER=`lpstat -d | awk '{print $NF}'`              
scanimage --mode gr --format tiff --resolution 300 -x 210 -y 290 | lpr -P$PRINTER -oscaling=100

All that remains is to have the ability to scan documents to PDFs…and again, bash and the command line comes to the rescue…you can download my scanpdf.bsh. It is designed for flatbed only scanners. Try running it with --help to see available options. You may click here to view the code.

#! /bin/bash -eu
# Version 1.01
# Last updated 11 March 2011
#
# DEFAULTS
#
SCANNER_MODE="col"   # try  "lin", "bin",  "gr", or "col"
SCANNER_RES=300
PDF_QUALITY=70
PDF_FORCE="colour"
#PDF_FORCE="monochrome"
PAGE_X=210
PAGE_Y=297
DESTFILE=$(pwd)
DM=`date +%d%b%y_%H%M%S`
DESTFILE="$DESTFILE/scan_$DM.pdf"
#
# CHECK COMMAND LINE PARAMS
#
p=0
for PARAM in "$@"
do
    p=$(( $p + 1 ))
    case "$PARAM" in
     "--file")
            #value is p+1
            v=$(( $p + 1 ))
            DESTFILE=${!v}     # note the ! = INDIRECT EXPANSION OF VARIABLES
           ;;
     "--resolution")
            #value is p+1
            v=$(( $p + 1 ))
            SCANNER_RES=${!v}     # note the ! = INDIRECT EXPANSION OF VARIABLES
            ;;
     "--mode")
            #value is p+1
            v=$(( $p + 1 ))
            SCANNER_MODE=${!v}     # note the ! = INDIRECT EXPANSION OF VARIABLES
            ;;
     "--quality")
           #value is p+1
            v=$(( $p + 1 ))
            PDF_QUALITY=${!v}     # note the ! = INDIRECT EXPANSION OF VARIABLES
            ;;
     "--force")
            #value is p+1
            v=$(( $p + 1 ))
            PDF_FORCE=${!v}     # note the ! = INDIRECT EXPANSION OF VARIABLES
            ;;
     "--pagesize")
            # A4 [DEFAULT] = 210 x 297
            # 6by4 = 152 x 101
            # 4by6 = 101 x 152
            #letter = 215.9 x 279.4
           #value is p+1
            v=$(( $p + 1 ))
            case ${!v} in
                "A4")
                    PAGE_X=210
                    PAGE_Y=297
                    ;;
                "6by4")
                    PAGE_X=152
                    PAGE_Y=101
                    ;;
                "4by6")
                    PAGE_X=101
                    PAGE_Y=152
                    ;;
                "letter")
                    PAGE_X=216
                    PAGE_Y=280
                    ;;
                *)
                    echo "Unrecognised page size! Valid options are: A4, 6by4, 4by6 and letter"
                    exit
                    ;;
            esac
            ;;
     "--help")
           echo -e "This will scan one or more pages, convert it to a PDF and save it in the present
directory. Possible switches are:
    --help              - this message
    --file ./somefile.pdf       - set a custom file name
    --resolution 300        - set scanning resolution
    --mode  greyscale       - set scanning mode
                    (lineart, binary, greyscale or color)
    --quality 70            - set PDF jpeg compression factor
                    (1-100, higher number better quality)
    --pagesize  A4      - set the page size, options are A4,
                    6by4, 4by6 or letter (A4 is the default)

Lineart and Binary are equivalent, which term you use depends on your driver.
Note that some of these options may not work as it depends on your hardware and driver compatibility. See http://www.sane-project.org/sane-mfgs.html for more
information.

For devices that do not support '--mode lineart' or '--mode binary', if you
wish to make a black and white PDF (e.g. for archival or OCR purposes) then use
the following switch:

    --force monochrome"

            exit
           ;;
     esac  
done
#
# Check that a scanner is attached
#
SCANNER_TEST=`scanimage -f %d`
if [ ${#SCANNER_TEST} == 0 ]
then
    echo -e "No scanner detected! Is the device plugged in and powered on?
Run 'scanimage -L' or 'sane-find-scanner' for further assistance"

    exit 1
fi
#
# check that we can write to destination file
#
if [ ! -w ${DESTFILE%/*} ]
then
    echo "Unable to write to ${DESTFILE%/*}"
    exit 1
fi
#
#
# Test for required programs.
if [[ -z $( type -p scanimage ) ]]; then echo -e "Error! scanimage (sane-utils) is not installed!";exit ;fi
if [[ -z $( type -p tiffcp ) ]]; then echo -e "Error! tiffcp (libtiff-tools) is not installed!";exit ;fi
if [[ -z $( type -p tiff2pdf ) ]]; then echo -e "Error! tiff2pdf (libtiff-tools) is not installed!";exit ;fi
#
# check for optional requirements - ImageMagick?
#
if [ $PDF_FORCE == "monochrome" ];
then
    if [[ -z $( type -p convert ) ]]; then echo -e "Error! convert (imagemagick) is not installed!";exit ;fi
fi
#
#
# create a temporary directory
TEMP_FLDR=`mktemp -d`
i=0
CONTINUE="Y"
while [ $CONTINUE == "Y" ] || [ $CONTINUE == "y" ]; do
    i=$(expr $i + 1)
    echo "Scanning page $i"
    scanimage --mode $SCANNER_MODE --format tiff --resolution $SCANNER_RES -x $PAGE_X -y $PAGE_Y > $TEMP_FLDR/out$i.tif
    #[scan an image, output to $TEMP_FLDR/out1.tif]
    # could also use batch or batch-prompt to do multiple page scans and or use ADF
    read -p "Do you wish to scan another page (Y or N)?  " -n 1 -e CONTINUE
done
if [ $i -gt 0 ]
then
    #is force monochrome set?
    if [ $PDF_FORCE == "monochrome" ];
    then
        FILES=$TEMP_FLDR/out*.tif
        for f in $FILES
        do
            convert "$f" -monochrome "$f"
        done
    fi
    # join tiff files together
    echo -e "Combining $i tiff files..."
    tiffcp -c lzw $TEMP_FLDR/out*.tif $TEMP_FLDR/output.tif
    #Convert the tiff to PDF
    echo -e "Creating $DESTFILE"
    tiff2pdf -j -q $PDF_QUALITY $TEMP_FLDR/output.tif > "$DESTFILE"
    #delete temp folder
else
    #nothing to do
    echo "No Pages scanned!"
fi
rm -rf $TEMP_FLDR
echo -e "Done."

2 Comments

  1. Tim says:

    Thanks for these scripts. I have had a laser printer for awhile, but got a cheap multifunction inkjet for scanning purposes, and this makes it very easy to photocopy and scan to pdf!

  2. bobby says:

    Cool script !
    I had to modify it slightly to get it to work on ubuntu14.04,
    ‘gray’ not ‘greyscale’ and changed
    ‘tiff2pdf -j -q $PDF_QUALITY …’ to ‘tiff2pdf -z …’ otherwise it produces a very reddish page for some reason.

Leave a Reply

*

Contact Nixz Kerr