[[Vorlage(Getestet, bionic)]]
[[Vorlage(Fortgeschritten)]] 

{{{#!vorlage Wissen
[:Pakete_installieren:Installation von Programmen]
[:sudo: Root-Rechte]
[:Rechte: Rechte für Dateien und Ordner ändern]
[:Editor: Einen Editor öffnen] 
[:Terminal: Ein Terminal öffnen] 
}}}
[[Inhaltsverzeichnis(2)]] 

[[Bild(Wiki/Icons/scanner.png, 48, left)]]
Viele Scanner haben Tasten, mit denen sich Vorlagen direkt kopieren, faxen oder mailen lassen. Leider ist Software, die diese Tasten überwacht und nutzbar macht, in vielen Fällen nur für proprietäre Betriebssysteme verfügbar. [sourceforge2:scanbuttond:] {en} hilft, diese Tasten auch unter Linux zu nutzen. Momentan werden Scanner von [:Scanner/Epson:Epson], [:Scanner/Canon:Canon], [:Scanner/Agfa_SnapScan:Agfa] und [:HPLIP:HP] unterstützt. Eine genaue Liste der jeweiligen Modelle findet man auf der [http://scanbuttond.sourceforge.net/index.php?page=/Supported_Scanners.php Hardwareseite] {en} der Projektseite.  Andere SANE-Scanprogramme haben dabei Vorrang, sie können gestartet werden, und unterbinden während ihres Betriebs die Tastenbedienung am Scanner. 

Das Programm wird schon seit etlichen Jahre nicht mehr weiterentwickelt - die Dateien auf Sourceforge stammen aus 2006 -  und unterstützt modernene Scanner nicht. Es gibt aber inzwischen einige [:Scanner/Software/#Tasten-am-Scanner-verwenden:Alternativen] zu scanbuttond.

= Installation =
Das in den Quellen vorhandene Paket '''scanbuttond''' beinhaltet nur noch eine "Wrapper"-Skript, das scanbuttond-Skripte für die neuere Software [:scanbd:] verwendbar machen soll. Allerdings kann problemlos von ein Paket [https://ubuntu.pkgs.org/14.04/ubuntu-universe-amd64/scanbuttond_0.2.3.cvs20090713-16_amd64.deb.html scanbuttond] {dl} von ubuntu.pkgs.org für Ubuntu 14.04 verwendet werden. Nach der Installation muss  eine "Aktualisierung" z.B. via [:Apt-Pinning:] verhindert werden, da das Dummy-Paket eine höhere Versionsnummer hat und ansonsten umgehend von einem Update überschrieben wird.

[[Vorlage(Fremd, Paket, "")]] 

= Konfiguration =
Die benötigten Dateien '''initscanner.sh''' und '''buttonpressed.sh''' existieren zunächst nur als Beispieldateien (angehängtes ".example") im Verzeichnis '''/etc/scanbuttond'''. Um diese Dateien umzubenennen und zu bearbeiten, benötigt man Root-Rechte [2]. Nachdem man die beiden Konfigurationsdateien erstellt bzw. umbenannt hat, müssen diese noch ausführbar gemacht werden [3].

Damit der Scanner auch gefunden wird, muss in der neu erzeugten Datei '''/etc/scanbuttond/initscanner.sh''' der Befehl

{{{
sane-find-scanner
}}}

aktiviert werden [4].

Nun startet man im Terminal [5] scanbuttond per 

{{{#!vorlage Befehl
scanbuttond -f
}}}

im Vordergrund. Wenn man jetzt die Tasten am Scanner drückt, sollte das Terminal eine Meldung ausgeben, die jeder gedrückten Taste eine eindeutige Nummer zuordnet. In etwa so: 

{{{
button 1 has been pressed on plustek:libusb:002:005
button 2 has been pressed on plustek:libusb:002:005
button 3 has been pressed on plustek:libusb:002:005
}}}

Diese Zuordnung sollte man sich merken, sie wird später bei der Einrichtung der Aktionen noch gebraucht. 

scanbuttond arbeitet mit Bash-Skripts, d.h. beim Drücken einer Scanner-Taste wird die Nummer der Taste an das Skript '''buttonpressed.sh''' im Verzeichnis '''/etc/scanbuttond/''' übergeben. Das Skript startet dann abhängig von der Taste eine Aktion. Im Skript sieht das dann ungefähr so aus: 

{{{
#!/bin/sh

# This script[...]like scanimage.

TMPFILE="/tmp/scan.tiff"
LOCKFILE="/tmp/copy.lock"

case $1 in
        1)
                echo "button 1 has been pressed on $2"
                ;;
        2)
                echo "button 2 has been pressed on $2"
                ;;
        3)
                echo "button 3 has been pressed on $2"
                ;;
        4)
                echo "button 4 has been pressed on $2"
                ;;
esac
}}}

Zunächst gibt das Skript nur aus, welche Taste gedrückt wurde; dieses Verhalten gilt es zu ändern. Dazu öffnet man die Skript-Datei mit einem Texteditor [3] und trägt die gewünschten Kommandos an den entsprechenden Stellen anstatt des echo-Befehls ein, z.B. `scanimage > bild.pnm`, um ein Dokument unter Verwendung der Standardeinstellungen einzuscannen und als '''bild.pnm''' zu speichern. Wenn nun die entsprechende Taste gedrückt wird, startet sofort die festgelegte Aktion, in diesem Fall das Speichern des Scans im eigenen Ordner. 

{{{#!vorlage Hinweis
Sollte ein Scanner mehr als 4 Tasten besitzen, so kann man das Skript einfach erweitern, indem man weitere nummerierte Zeilen unter '4)' einfügt. 
}}}

{{{#!vorlage Experten
Anstatt die Kommandos direkt in '''buttonpressed.sh''' einzutragen, könnte man weitere Skripte aufrufen.
}}}

Hat man die gewünschten Änderungen getätigt, speichert man die Datei. Nun kann man noch im  [:Autostart:] den Eintrag `scanbuttond -f` hinzufügen und zukünftig nach jeder Anmeldung die programmierten Scannertasten sofort nutzen. 

= Skript-Beispiele =

{{{#!vorlage Hinweis
Um diese Skripte nutzen zu können, müssen die Pakete
{{{#!vorlage Paketinstallation
netpbm
libtiff-tools
\}}}

installiert [1] sein.

Außerdem müssen die Skripte ausführbar[3] gemacht werden.

Ggf. sind nicht alle in den Skripten verwendeten Option für alle Scanner verwendbar - Auskunft darüber erhält man mit dem Aufruf von `scanimage --help`.
}}}

Hier das für Skripte angepasste '''buttonpressed.sh''' sowie einige Beispiel-Skripte für Scannen, Kopieren und Mailen. 

{{{#!code bash
#!/bin/sh
TMPDIR="$HOME/Desktop"                              #hier wird ein Verzeichnis für die Datei festgelegt; durch die Verwendung der Umgebungsvariable $HOME wird jedesmal der Desktop des aktuellen Benutzers verwendet
TMPFILE="$TMPDIR/scan`date +%Y%m%d`-`date +%H%M%S`" #wir generieren uns hier den Dateinamen für das spätere Ergebnis; der Name besteht aus dem Präfix scan und wird jedesmal um Datum und Uhrzeit ergänzt
                                                    #Dateinamenerweiterungen werden später hinzugefügt
LOCKFILE="/tmp/copy.lock"                           #Variable für das Lockfile, das kennzeichnet, ob der Scanner schon in Benutzung ist; wird hier nicht verwendet

case $1 in
        1)      echo "Button 1 pressed"                        #wird Button 1 gedrückt so wird eine Meldung ausgegeben (nur sichtbar, wenn scanbuttond im Vordergrund läuft - zum Debuggen)
                $HOME/.scanscripts/scan.sh $TMPFILE $DEVICE    #und das Skript scan.sh im versteckten Ordner .scanscripts im Homeverzeichnis gestartet; zusätzlich werden noch Name und Ort des Tempfiles,
                ;;                                             #sowie die Adresse des Scanners übergeben, sinnvoll bei mehr als einem Scanner

        2)      echo "Button 2 pressed"                        #wird Button 2 gedrückt, so wird eine Meldung ausgegeben (siehe oben)
                $HOME/.scanscripts/copy.sh $TMPFILE $DEVICE    #und das Skript copy.sh im versteckten Ordner .scanscripts im Homeverzeichnis gestartet; zu übergebenen Attributen siehe oben
                ;;
        3)      echo "Button 3 pressed"                        #wird Button 3 gedrückt, so wird eine Meldung ausgegeben (siehe oben)
                $HOME/.scanscripts/mail.sh $TMPFILE $DEVICE    #und das Skript mail.sh im versteckten Ordner .scanscripts im Homeverzeichnis gestartet; zu übergebenen Attributen siehe oben
                ;;
esac

}}}

Hier das Skript zum einfachen Scannen ('''scan.sh''')

{{{#!code bash
#!/bin/sh
TMPFILE=$1 #Enthält zukünftigen Speicherort und Dateiname des Scans

scanimage --format pnm --mode Color --depth 8 --resolution 300 -l 0 -t 0 -x 215mm -y 280mm --lampoff-time 300 > ${TMPFILE}.pnm #scanimage scannt die Vorlage und speichert sie als Dateiname.pnm,
                                                                                                                               #die einzelnen Optionen sind von Scanner zu Scanner unterschiedlich (hier Farbscan
                                                                                                                               #in einer Auflösung von 300dpi)

pnmtojpeg -quality 85 -optimize -comment "was immer man als Kommentar haben will" $TMPFILE.pnm > $TMPFILE.jpeg # die .temp-Datei wird mittels pnmtojpeg in eine jpeg-Datei umgewandelt und dabei komprimiert

rm -f $TMPFILE.pnm  #jetzt muss nur noch die temporäre Datei gelöscht werden
}}}

Und hier zum Kopieren ('''copy.sh''')

{{{#!code bash
#!/bin/sh

TMPFILE=$1  #siehe Skript zum Scannen
scanimage --format tiff --mode Gray --resolution 300 --brightness -3 -l 0 -t 0 -x 215mm -y 297mm > ${TMPFILE}.tiff  #scannt das Bild ein und speichert es als tiff (hier in Graustufen und Auflösung 300dpi)

tiff2ps -z -w 8.27 -h 11.69 $TMPFILE.tiff | lpr   # eingescanntes Bild wird in Postscript umgewandelt und an den Standarddrucker gesendet

rm -f $TMPFILE.tiff  #temporäre Datei wird gelöscht

}}}

Zum Schluss noch eines zum Versenden per Mail ('''mail.sh'''):

{{{#!code bash
#!/bin/sh

TMPFILE=$1  #siehe Skript zum Scannen
scanimage --format pnm --mode Color --depth 8 --resolution 300 -l 0 -t 0 -x 215mm -y 280mm --lampoff-time 300 > ${TMPFILE}.pnm  #scannt das Bild ein und speichert es als pnm

pnmtojpeg -quality 85 -optimize -comment "was immer man als Kommentar haben will" $TMPFILE.pnm > $TMPFILE.jpeg    #wandelt das Bild von pnm zu jpeg um

rm -f ${TMPFILE}.pnm #temporäre Datei wird gelöscht

#hier wird Evolution zum Versenden eingesetzt
evolution --display=:0.0 "mailto:?attach=$TMPFILE.jpeg" #öffnet Evolutions Maileditor und fügt das Bild als Anhang hinzu
}}}

Falls scanbuttond nicht über einen Eintrag in die '''rc.local''' gestartet wurde, sondern der Dienst über die '''/etc/default/scanbuttond'''-Datei aktiviert wurde, kann es beim mail-Skript zu folgender Fehlermeldung kommen:

{{{
Cannot start Evolution. Another Evolution instance may be unresponsive. System Error: Cannot autolaunch D-Bus without X11 $DISPLAY
}}}

Abhilfe schafft es ggf., in der letzte Zeile Evolution mit folgendem Befehl aufzurufen:

{{{
$(DISPLAY=:0 evolution "mailto:?attach=$TMPFILE.jpeg")
}}}

==  PDF mit Textlayer ==

Um eine PDF-Datei mit Textlayer zu erstellen (verwendet wird [:OCRmyPDF:]) kann folgendes Skript (z.B. als '''pdf.sh''') verwendet werden, was man zweckmäßigerweise mit dem PDF-Knopf am Scanner aufruft (dazu das '''buttonpressed.sh''' entsprechend erweitern):
{{{#!code bash
#!/bin/sh

TMPFILE=$1  #siehe Skript zum Scannen
scanimage --format tiff --mode Gray --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.tiff  #scannt das Bild ein und speichert es als tiff (hier in Graustufen und Auflösung 300dpi)

tiff2pdf -o ${TMPFILE}.pdf ${TMPFILE}.tiff  # eingescanntes Bild wird in Pdf umgewandelt und an ocrmypdf übergeben
ocrmypdf -l deu -C no_ligature ${TMPFILE}.pdf ${TMPFILE}.OCR.pdf

rm -f $TMPFILE.tiff  #temporäre Datei wird gelöscht
rm -f $TMPFILE.pdf   #temporäre PDF-Datei wird gelöscht

}}}

= Mehrfachbelegung von Tasten =
Mit etwas Puzzlearbeit ist es möglich, die Tasten des Scanners mit mehreren Funktionen zu belegen. Im folgenden Beispiel wird die Copy-Taste mit den Funktionen S/W-Kopie (ein Tastendruck), Graustufen-Kopie (zwei Tastendrücke) und Farb-Kopie (drei Tastendrücke) belegt. Bei mehr als drei Tastendrücken innerhalb einer Zeitraumes von 5 Sekunden (anpassbar in Zeile 3) wird eine Fehlermeldung ausgegeben. Das hier vorgestellte Beispiel arbeitet mit [:yad:] und [:usbreset:], um ggf. Fehler bei der Scannerfreigabe zu kompensieren. Das Skript sollte statt über einen Autostart-Eintrag in '''rc.local''' über die Datei '''/etc/default/scanbuttond''' gestartet werden, in der neben `RUN=yes` auch `RUN_AS_USER=BENUTZER` eingetragen werden sollte. In '''/etc/init.d/scanbuttond''' ebenfalls den Benutzer ändern, außerdem in Zeile `DAEMON_OPTS=` den Wert `"-p 10000"` eintragen (damit wird das Zeitintervall angegeben, wie oft scanbuttond überprüft, ob neue Tastendrücke erfolgt sind).

Zur Verwendung wird in '''/etc/scanbuttond/buttonpressed.sh''' folgender Eintrag für die entsprechende Taste abgespeichert:

{{{
                echo "Button 1 pressed - copy" >> /tmp/scanbutton.log 2<&1                       #wird Button 1 gedrückt so wird eine Meldung ausgegeben (nur sichtbar, wenn scanbuttond im Vordergrund läuft - zum Debuggen, hier wird in die Log-Datei geschrieben)
		PID_FILE=/tmp/scanbutton.pid
		if [ -e $PID_FILE ]; then
    		kill -SIGUSR1 $(<"$PID_FILE") 2>&1 |: #>> /tmp/scanbutton.log
		else
    		rm -f /tmp/scanbutton.log
   		nohup /PFAD/ZUM/.scanscripts/copy_counter.sh $TMPFILE $DEVICE >> /tmp/scanbutton.log 2<&1 < /dev/null &
		fi
}}}
Das Skript muss ggf. als bash-Skript gespeichert werden, dazu die [:shebang:] auf `#!/bin/bash` ändern. Den Pfad zum '''copy_counter.sh'''-Skript entsprechend anpassen.

Das Skript selbst in einen Editor kopieren und als '''copy_counter.sh''' abspeichern und ausführbar machen:
{{{#!code bash
#!/bin/bash

TIMEOUT=5 # count button presses after n seconds and take appropriate actions
PID_FILE=/tmp/scanbutton.pid
echo $$ > $PID_FILE  # create a file with our pid

declare -a BTN_PRESSED
BTN_PRESSED+=($(date +%s))

function cleanup {
    rm -f "$PID_FILE"
}

function check_runtime {
    if [[ ${BTN_PRESSED[0]} -lt $(date +%s -d "$TIMEOUT seconds ago") ]]; then
        return 1  # the oldest timestamp is older than $TIMEOUT
    else
        return 0
    fi
}

# reset usb-connection
function usbrestart {
	usbreset /dev/bus/usb/002/004 2>&1 >> /tmp/scanbutton.log
}

#scan image
function scan_color {
	if [[ "$SCANCOLOR" == "BW" ]]; then
	scanimage --format pnm --mode Lineart --custom-gamma=yes --gamma-table 30000 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.pnm 2> /tmp/scanimage.txt
	elif [[ "$SCANCOLOR" == "GR" ]]; then
	scanimage --format pnm --mode Gray --swcrop=yes --swdeskew=no --custom-gamma=yes --gamma-table 30000 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.pnm 2> /tmp/scanimage.txt
	elif [[ "$SCANCOLOR" == "CL" ]]; then
	scanimage --format pnm --mode Color --swcrop=no --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.pnm 2> /tmp/scanimage.txt
	fi
}
#print image
function print_tiff {
	lpr ${TMPFILE}.pnm
	echo "Scan sent to printer, ~~~`date +%Y%m%d`-`date +%H%M%S`"
	rm -f ${TMPFILE}.pnm #2>&1 > /dev/null |: #temporäre Datei wird gelöscht
}
# check if SANE-decive is usable, if not reset usb-device and restart the whole process
function check_device {
	CHECK=`cat "/tmp/scanimage.txt"`
 	if [[ $CHECK != "" ]] ; then
		$(DISPLAY=:0 yad --on-top --center --timeout=5 --title="Device problem..." --text="Ooops - problems with the scanner! \nScript trys to reset usb connection!")
		echo "device problem `date +%Y%m%d`-`date +%H%M%S`"
		echo "$CHECK"
		usbrestart
		scan_color
		echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
		print_tiff
		rm -f /tmp/scanimage.txt
		exit 0
	fi 
}

trap 'cleanup; exit 0' SIGTERM SIGINT
trap cleanup EXIT
trap "BTN_PRESSED+=($(date +%s));" SIGUSR1


while check_runtime; do
    sleep 0.11  # if the button presses have a shorter delta t, then reduce this value
done

echo "~~~`date +%Y%m%d`-`date +%H%M%S`"
echo "Button has been pressed at ${BTN_PRESSED[@]}"

case ${#BTN_PRESSED[@]} in
1) echo "action #1, b/w-copy A4"
TMPFILE=$1
SCANCOLOR=BW
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
2) echo "action #2 Grayscale-copy A4"
TMPFILE=$1
SCANCOLOR=GR
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
3) echo "action #3, Color-copy A4"
TMPFILE=$1
SCANCOLOR=CL
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
*) echo "too many button presses"
esac


rm -f /tmp/scanimage.txt

}}}

Jetzt sollte bei entsprechenden Tastendrücken direkte Kopien im Din-A4-Format entstehen. Das Skript ist für einen CanoScan LiDE 60 ausgelegt, ggf. müssten einige Optionen an die Gegebenheiten des eigenen Scanners angepasst werden. Fehlermeldungen werden in der '''.log'''-Datei '''/tmp/scanbutton.log''' aufgeführt. Falls der Scanner nicht erkannt wird, versucht das Skript, den USB-Anschluss via usbreset neu zu starten und den Auftrag zu wiederholen - yad öffnet dazu ein Hinweisfenster.

Besonderer Dank geht an [user:seahawk1986:], der maßgeblich an der Entwicklung beteiligt war, siehe dazu auch diesen [topic:scanner-tastendruecke-in-einem-bestimmten-zeit:Thread] im Forum.

= Alternativen =
 * [:Scanner/Software/#Tasten-am-Scanner-verwenden:Tasten am Scanner verwenden] {Übersicht} - Übersicht
  * [:scanbd:] - modernere Alternative für SANE-fähige Scanner.
  * [:insaned:] - einfaches Programm, um Tasten zu verwenden, ohne Anspruch auf gleichzeitige anderweitige Nutzung des Scanners.
  * [:bscand:] - ein Programm, das durch eine gepatchte SANE-backend-Version die Tasten direkt zugänglich macht; verwendet das net-backend.
  * Für Brother-Scanner kann das Programm [:Scanner/Brother/Scankey-Tool:Scankey-Tool] verwendet werden.

= Links =
 * [sourceforge2:scanbuttond:Projektseite] {en}
 * [sourceforge2:scanbd:] {en} - jüngere Alternative zu scanbuttond
 * [http://wikigentoo.ksiezyc.pl/Scanner_buttons_and_one-touch_scanning.htm Gentoo-Wiki-Eintrag] {en} in dem u.a. ein Weg beschrieben wird, nicht unterstützte Scanner mit aufzunehemn; dazu muss allerdings der sourcecode bearbeitet, und das Programm selbst kompiliert werden.

# tag: Hardware, Scanner