Scannen per Tastendruck auf dem Canon LIDE 20

Hardware

Der Canon LIDE 20, auch unter dem Namen CanoScan N670U bekannt, scannt nicht nur in einer guten Qualität und akzeptablen Geschwindigkeit - er gehört auch noch zu den rar gesäten Geräten, die unter Linux mit echtem Plug and Play funktionieren. Abgesehen von den drei Tasten an der Vorderseite des Scanners. Unter anderen Betriebssystemen kann man mit diesen Tasten sozusagen im Schnellverfahren Scannen, Kopieren und das Gescannte per Mail verschicken. Nun zähle ich mich nicht zu den Usern, die täglich ihren Scanner benutzen, deshalb störten mich die funktionslosen Tasten unter Linux nicht. Aber irgendwann packt einen doch der Ehrgeiz - und seien wir mal ehrlich - für eine Kopie erst eine Konsole aufmachen und einen Befehl eintippen, wenns auch einfacher geht, das ist nicht Linux-like.

Vorrausetzungen

Milan Zamazal ist der Entwickler des Paketes scanbuttond, einem Daemon, der die Tasten von diversen Scannern überwacht. Das Paket sollte sich in jeder gängigen Distribution finden lassen. Unterstützt werden alle Scanner die auf folgenden Backends basieren:

  1. usb
  2. epson
  3. meta
  4. mustek
  5. niash
  6. plustek
  7. snapscan

Außerdem sollten die Pakete sane-utils und consolekit installiert sein.

Der Daemon ruft nach einem Tastendruck am Scanner das Script /etc/scanbuttond/buttonpressed.sh auf. In dem Paket ist auch ein rudimentär gehaltenes Beispielscript enthalten. Hier beginnt also die eigentliche Arbeit.

Daemon starten - aber richtig

Vorher müssen wir uns noch Gedanken machen, wann der Daemon eigentlich gestartet werden soll und mit welchen Rechten. Letzteres hat Auswirkungen auf das Script /etc/scanbuttond/buttonpressed.sh und die von ihm angelegten Dateien. Ist der Scanner immer am System angeschlossen und gibt es nur einen Benutzer im System, kann man den Dienst am einfachsten über die Autostart-Funktionen des Desktopsystems des Benutzers starten. Beim LIDE 20 handelt es sich aber um einen USB-Scanner, der muß nicht zwangsläufig fest am System angeschlossen sein. Eine udev-Regel, die den Dienst beim Erkennen des Scanners startet, wäre also der richtige Ansatz. Beginnen wir also damit.

Udev-Regel

Mit Hilfe von udevinfo holen wir uns die benötigten Informationen, um den Scanner eindeutig zu identifizieren. Die Regel selbst sieht dann so aus:

SUBSYSTEM=="usb", ATTR{idProduct}=="220d", ATTR{idVendor}=="04a9", RUN+="/usr/bin/start_scanner.sh"

Die udev-Regel selbst gehört ins Verzeichnis /etc/udev/. Nicht vergessen, im Verzeichnis /etc/udev/rules.d/ einen Link auf die Regel zu setzen.

Wie Ihr hoffentlich richtig bemerkt habt, startet die udev-Regel nicht den eigentlichen Daemon, sondern ein Script /usr/bin/start_scanner.sh. Das hat seinen Grund. Nehmen wir an, im Laufe eines langen Tages habt Ihr irgendwann etwas zu scannen. Ihr steckt also den Scanner an und udev startet den Dienst scanbuttond. Danach braucht Ihr den USB-Port z.B. für eine USB-Festplatte. Scanner ab, Dienst läuft weiter, USB-Festplatte ran. Später müßt Ihr wieder was scannen, also Scanner wieder anschließen. In diesem Moment wird der Dienst ein zweites Mal gestartet, was zu Problemen beim Erkennen der Tasten führen kann. Nun könnte man den RUN-Eintrag in der udev-Regel dahingehend abändern, daß er erst prüft, ob der Dienst noch nicht läuft und ihn dann startet. Das wird aber schnell unübersichtlich und ein Script ist besser zu warten. Deshalb habe ich das Script /usr/bin/start_scanner.sh dazwischen geschaltet.

#!/bin/bash
typeset -i retval
if [[ -f /usr/bin/scanbuttond ]]; then
	if [[ $(pidof scanbuttond) == "" ]]; then
		scanbuttond
		scanimage -L
		retval=${?}
	fi
else
	retval=1
fi
exit ${retval}

Das scanimage -L initialisiert sozusagen den Scanner. Eine zweite Möglichkeit wäre, durch die udev-Regel einen Link auf das eigentliche Gerät zu erstellen, mittels iwatch, das /dev-Verzeichnis auf das Löschen dieses Links beim Abziehen des Scanners zu überwachen und dann den Daemon zu beenden. Dann könnte in der udev-Regel der Dienst direkt gestartet werden. Das wäre noch eine Überlegung wert.

Das Script buttonpressed.sh

Unser Dienst wird jetzt also korrekt gestartet und wartet auf einen Tastendruck am Scanner. Die eigentlichen Aktionen werden im Script /etc/scanbuttond/buttonpressed.sh ausgelöst. Die Aktionen selbst sind im Case-Abschnitt untergebracht. Weiter oben haben wir schon ein Rechteproblem angesprochen. Der Dienst selbst wird durch udev mit den Rechten von Root gestartet und startet seinerseits auch das Script buttonpressed.sh mit den Rechten von Root. Das bedeutet, alle angelegten (eingescannten) Dateien gehören Root. Für temporär angelegte Dateien mag das ja noch angehen, aber die eingescannten Dokumente sollten schon im richtigen /home-Verzeichnis landen und dem entsprechenden User gehören. Im Script wird deshalb erst einmal ermittelt, wer an dem gerade aktiven X-Display angemeldet ist. Nach dem Scannen werden mit chown die Dokumente dem Users übergeben und mittels su auf dem richtigen X-Display angezeigt. Einzig das Kopieren von Dokumenten ist auch von einer normalen Shell aus möglich.

Die Aktion der ersten Taste für das Scannen enthält noch eine Funktion zur fortlaufenden Nummerierung der Dateinamen, damit keine Datei überschrieben wird. Mit scanimage wird gescannt und das eingescannte Bild wird mit kview angezeigt.

Die Funktion der zweiten Taste zum Kopieren ist anspruchslos. Mit scanimage wird gescannt, mit tiff2ps nach Postscript gewandelt und per Pipe an lpr geschickt.

Die dritte Funktion Mail scannt wiederum mit scanimage, convert verkleinert das Bild auf max. 1024 Pixel und wandelt nach jpg. Anschließend wird mit steghide ein Copyrigth im Bild versteckt. Dazu muß im Home-Verzeichnis eine Datei .steghide/copyright.txt mit dem Text des Copyrights und eine Datei .steghide/passphrase.txt mit dem Passwort für steghide nach dem Muster:

passphrase geheim

vorhanden sein. Wer diese Funktion nicht benötigt, kann sie einfach auskommentieren. Zu guter Letzt wird in Kmail eine neue Mail mit der Datei als Anhang geöffnet.

Wer von Euch gnome oder Xfce verwendet oder andere Programme zum Anzeigen bzw. Mailversand benutzt, muß natürlich die entprechenden Zeilen durch die Befehle für seine bevorzugten Programme ersetzen.

Die udev-Regel und die beiden Scripte gibts hier zum Download. Wie immer bin ich für Rückmeldungen jeglicher Art und Verbesserungsvorschläge dankbar.