Author: Manolis Tzanidakis
I run Ubuntu 6.10 (Egdy Eft) on my desktop system, but all required programs are available on most Linux distributions and, possibly, BSD variants. The actual programs you will need for this setup are:
scanimage, the scanning command of the SANE package. In Ubuntu/Debian this command is included in the sane-utils package.
convert, part of the ImageMagick image manipulation suite. We will use this program to convert the scanned pictures to different formats. On Ubuntu/Debian install the imagemagick package. This article is a nice introduction to the powerful ImageMagick suite.
scanbuttond is the daemon program that does all the dirty work of running commands when a scanner button is pressed. For more information check its home page. On Ubuntu and Debian (testing and unstable only) install the scanbuttond package.
Optionally, you can also install the zenity package (installed by default on Ubuntu) to print nice, graphical error messages when something goes wrong.
Before continuing you need to make sure that your scanner operates correctly under Linux. A previous tutorial, How to share a scanner on your network, contains information on how to set up your scanner on Linux. Read the first part of that article and make sure that running scanimage -L
as your regular, non-root user lists your scanner. This command on my system returns:
device `plustek:libusb:004:002' is a Epson Perfection 1260/Photo USB flatbed scanner
To start, you need to adjust scanimage’s options manually to achieve the best scanning results. Grab a ruler and measure your scanner’s actual scanning surface — X and Y axis — or find these values in your scanner’s manual. Put a nice color picture on your scanner and run the command scanimage --device "plustek:libusb:004:002" --mode Color --resolution 300 --depth 8 -x 215 -y 297 > ~/test.pnm
to scan the image and save it as test.pnm in your home directory. Make sure to replace plustek:libusb:004:002 with the device printed by running scanimage -L
, and the values of -x and -y with the dimensions of your scanner. 215 and 297 are my scanner’s scanning surface dimensions in mm (millimeters). Don’t worry if you get these dimensions wrong; scanimage will round them to the correct values automatically. For example, when I entered 220 as the length of the X axis, scanimage returned:
scanimage: rounded value of br-x from 220 to 215
The other options supplied to the scanimage command instruct it to scan a picture in Color mode (–mode) with 8 bits per sample (–depth) and 300dpi resolution (–resolution). These options should be enough for most users. For all available options run scanimage -h | less
and check the scanimage man page.
View the scanned picture test.pnm on your favorite image viewing program and adjust scanimage’s options to your liking. Write the adjusted command down somewhere since you’ll need it later.
Scanbuttond configuration
Scanbuttond has three configuration files — meta.conf, buttonpressed.sh, and initscanner.sh — all installed under the /etc/scanbuttond directory on Ubuntu. The first file, meta.conf, defines which scanner backend libraries will be used. You shouldn’t need to edit it unless you test a beta version and you’re told so by the program’s developers.
Some scanners might need some extra initialization steps — such as firmware uploading or running some commands — before they can be used by scanbuttond. You can enter these commands into the initscanner.sh file, which is actually a shell script run by scanbuttond during initialization. For my scanner, which is supported by the plustek backend, I had to add scanimage -n to that file. For more information on using initscanner.sh, check the paragraph titled “Scanner initialization” on scanbuttond’s README file (in Ubuntu/Debian it’s installed as /usr/share/doc/scanbuttond/README.gz) and SANE’s documentation for your scanner.
The last file, buttonpressed.sh, is the most interesting. It defines which commands should run when the buttons are pressed. It’s a shell script that’s run by scanbuttond with the button number as the first argument ($1) and the scanner device as the second ($2). By default the only thing it does is print the button’s number when it’s pressed. Run scanbuttond as your regular, non-root user and check its logs by running sudo tail -f /var/log/daemon.log
on a virtual terminal. If scanbuttond starts without problems you should see something similar to this:
Dec 14 19:37:18 my_hostname scanbuttond: found scanner: vendor="Epson",
product="Perfection 1260", connection="libusb", sane_name="plustek:libusb:004:002" Dec 14 19:37:18 my_hostname scanbuttond: scanbuttond started
Now press the scanner’s buttons while keeping an eye on the log tail command’s output to verify that all of your scanner’s buttons work. You should see something like:
Dec 14 19:37:37 my_hostname scanbuttond: button 1 has been pressed. Dec 14 19:37:37 my_hostname scanbuttond: button 1 has been released.
Now it’s time for the fun part. Back up the original buttonpressed.sh file by renaming it to buttonpressed.sh.orig and paste the following as a new buttonpressed.sh file:
#!/bin/sh # daemon's name DAEMON=scanbuttond # securely create temporary file to avoid race condition attacks TMPFILE=`mktemp /tmp/$DAEMON.XXXXXX` # lock file LOCKFILE="/tmp/$DAEMON.lock" # device name DEVICE="$2" # destination of the final image file (modify to match your setup) DESTINATION="/home/manolis/Desktop/scanned_image.jpg" # remove temporary file on abort trap 'rm -f $TMPFILE' 0 1 15 # function: create lock file with scanbuttond's PID mk_lock() { pidof $DAEMON > $LOCKFILE } # function: remove temporary and lock files clean_up () { test -e $LOCKFILE && rm -f $LOCKFILE rm -f $TMPFILE } # function: check if lock file exists and print an error message with zenity (if it's installed) chk_lock() { if [ -e $LOCKFILE ]; then if [ -x /usr/bin/zenity ]; then zenity --display :0.0 --title="Scanbuttond" --error --text="Another scanning operation is currently in progress." fi exit 1 fi } # function: the actual scan command (modify to match your setup) scan() { scanimage --device-name "$DEVICE" --mode Color --resolution 300 --depth 8 -x 215 -y 297 > $TMPFILE } case $1 in 1) # button 1 (scan): scan the picture & save it as $DESTINATION chk_lock; mk_lock; scan; convert $TMPFILE -quality 85 -quiet $DESTINATION; clean_up ;; 2) # button 2 (copy): scan the picture, convert it to postscript and print it chk_lock; mk_lock; scan; convert $TMPFILE ps:- | lpr; clean_up ;; 3) # button 3 (mail): scan the picture, save it as $DESTINATION and send it as an e-mail # attachment with Evolution chk_lock; mk_lock; scan; convert $TMPFILE -quality 85 -quiet $DESTINATION evolution --display=:0.0 "mailto:?attach=$DESTINATION"; clean_up ;; 4) # button 4 (web): unconfigured echo "button 4 has been pressed on $2" ;; esac
This script looks more complicated than it actually is; each command is explained in detail in the included comments (lines starting with #). The lines you need to edit are marked with notes that say (modify to match your setup). To make a long story short it scans, copies, and emails (with Evolution) a picture when you press buttons 1, 2, and 3, respectively. The convert program is used to convert the scanned image to the JPEG format when you press buttons 1 and 3, and converts the image to PostScript (PS) when you press button 2. You can find more information about convert’s features and options on its man page (man convert).
I left button 4 unconfigured as an exercise for the reader. You could try combining one of the utilities mentioned in this article with a scanner button to automate uploading scanned pictures to your Flickr account.
Make this new buttonpressed.sh file, as well as initscanner.sh, executable with chmod 755 /etc/scanbuttond/{buttonpressed,initscanner}.sh
. Stop scanbuttond, if it’s already running, with killall -TERM scanbuttond
. To start scanbuttond automatically when you log in, add it to your desktop environment’s session startup list. For example, on GNOME go to the menu System -> Preferences -> Sessions > Startup Programs.
Conclusion
When fine-tuned, scanbuttond can increase your productivity by automating your basic scanning tasks, or you can use it just to impress your friends at your local LUG. It can also be used for fun — you could for instance combine it with a USB Missile Launcher and play a prank on your colleagues.