Open Source im professionellen Einsatz
Linux-Magazin 12/2015
© panom pensawang, 123RF

© panom pensawang, 123RF

Ein mit Perl getunter Etikettendrucker spuckt Labels und QR-Codes aus

Ordnungshalber

Etiketten bringen Ordnung in den Kabelverhau am Heim-Router und helfen beim Zuordnen von in Kisten gelagertem Plunder. Mit einigen Handgriffen druckt Michael Schillis Labelwriter sogar unter Linux.

1619

Online PLUS

Im Screencast demonstriert Michael Schilli das Beispiel: http://www.linux-magazin.de/Ausgaben/2015/12/plus

Seit Jahrzehnten beschrifte ich meine Netzwerkkabel mit dauerhaften Etiketten aus einem tragbaren Gerät der Firma Brother (Abbildung 1). Doch bei jedem gedruckten Papperl regt mich der verschwenderische Umgang des Geräts mit dem Rohmaterial (Abbildung 2) auf, das ich in relativ teuren Kartuschen nachkaufen muss.

Abbildung 1: Schnelle Diagnose dank Ordnungssystem: Die konfigurierte IP-Adresse und die Wifi-SSID auf dem Router.
Abbildung 2: Verschwendet teures Etiketten-Rohmaterial: Der tragbare Brother-Etikettendrucker.

Brother-Ingenieure haben das Gerät wohl absichtlich so dilettantisch gebaut, dass es doppelt so viel Label-Band verbraucht als notwendig, auf dass der Rohbandkassetten-Absatz in die Höhe schnelle! Falls es eine Hölle gibt, erwarte ich, dass die verantwortlichen Produktmanager dort bald hinabfahren. Außerdem dauert es jedes Mal eine Ewigkeit, Texte wie "192.168.0.1" auf der unorthodoxen Tastatur einzutippen, das ginge mit meinem Desktoprechner viel schneller.

Schneller als von Hand

Auf Ebay fand ich einen Etikettendrucker, der sich via USB-Anschluss an meinen Ubuntu-Desktop stöpseln lässt. Der Labelwriter 450 Turbo von Dymo (Abbildung 3) kostete gebraucht etwa 40 Dollar und funktionierte auf Anhieb. Die Treiber für das Druckersystem Cups liegen als Sourcecode auf [2] bereit.

Abbildung 3: Der Etikettendrucker Labelwriter 450 Turbo der Firma Dymo druckt auch unter Linux.

Nach der Installation einiger Zusatzpakete wie »libcups2-dev« und »libcupsimage2-dev« mit »apt-get« kompiliert »./configure; make« das Ganze ohne Murren, »sudo make install« installiert die Cups-Dateien. Erst später fand ich heraus, dass die Ubuntu-Distribution ein einfach zu installierendes Paket enthält: »sudo apt-get install printer-driver-dymo« erledigt alles in einem Rutsch.

Nach der Installation der Cups-Treiber erkennt Ubuntu den neuen Etikettendrucker ohne Umschweife. Der Aufruf »lpstat -p -d« zeigt alle verfügbaren Drucker und ihren Status an:

printer LabelWriter-450-Turbo is idle.

Wer sich für die vom Treiber unterstützten Etikettengrößen interessiert, kann diese mit »lpoptions -p LabelWriter-450-Turbo -l« abfragen. Unter »Printers« in den Systemeinstellungen kommt dann, wie in Abbildung 4 gezeigt, ein Dialog hoch, in dessen Untermenü »Printer Options« sich die Abmessungen der verwendeten Etiketten einstellen lassen.

Abbildung 4: Ubuntu erkennt den Etikettendrucker und bietet die Einstellung der Etikettengröße an.

Ich kaufte eine Rolle mit der Bezeichnung "30330" mit 500 Stück so genannter Return Address Labels, die Firmen wohl als Absenderaufkleber verwenden. Mir sollte das recht sein, ich war lediglich an dem handlichen Format von 19 mal 51 Millimetern interessiert. Die Etiketten kommen senkrecht aus dem Thermodrucker geschossen, also sollte die Beschriftung ebenfalls in dieser Richtung erfolgen, das heißt um 90 Grad gedreht im Querformat. Wie schickt nun der Rechner den zu druckenden Text an das Gerät?

Das Cups-Druckersystem [3] bietet dazu den Befehl »lpr« an, der, wie in Listing 1 gezeigt, mit der Option »-P LabelWriter-450-Turbo« den Etikettendrucker auswählt, falls dieser nicht sowieso schon als Default-Drucker konfiguriert ist. Die Abmessungen der Etiketten gibt die Option »PageSize« vor. Die erwartet deren Längen- und Breiten-Angaben – aber nicht etwa in Millimetern oder gar Inches, sondern in Points.

Listing 1

cmd-print

1 lpr -P LabelWriter-450-Turbo -o PageSize=w54h144.1 label.pdf

Eine kurze Google-Suche offenbart, dass man für die Umrechnung in Points Millimeter mit etwa 1,8 multiplizieren muss (Abbildung 5). Aus den gewünschten 19 mal 51 Millimeter großen Etiketten werden auf diese Weise Rechtecke im Format 54 mal 144,1 Points, und der verwendete Parameter definiert genau dies: »PageSize= w54h144,1« .

Abbildung 5: Laut der verwendeten Umrechnungstabelle entsprechen 19 Millimeter etwa 54 Points.

Als letztes Kommandozeilenargument erwartet der »lpr« -Befehl jetzt noch den Namen der PDF-Datei, in der der gesetzte Drucktext bereitliegt.

Formatieren als PDF

Dieses Layout generiert Listing 2 mit Hilfe des CPAN-Moduls PDF::Create. Das Skript nimmt auf der Kommandozeile eine Zeichenkette entgegen, zum Beispiel

label-format "Hip-hip, hurra!"

und pflanzt sie in die Mitte eines PDF-Dokuments im Querformat mit den Maßen 144,1 mal 54 Punkt. Zu beachten ist, dass der Aufruf umschließende Anführungszeichen verlangt, falls die Zeichenkette Leerzeichen enthält. In manchen Shelldialekten müssen sogar Ausrufezeichen maskiert werden, da die Shell sie sonst als Aufrufe ihrer History-Funktion interpretiert. Die Formel

20 / length( $string ) * 11;

in Zeile 16 von Listing 2 rührt daher, dass ein String mit elf Zeichen bei einer Fontgröße von 20 Punkt beim Experimentieren genau die Länge des Labels ausfüllte. Längere Zeichenketten erfordern eine lineare Verkleinerung des Fonts, sodass auch diese auf das Etikett passen. Die einfache Formel funktioniert erstaunlich gut, weil der gewählte Helvetica-Font keine Proportionalschrift schreibt, sondern jedem Buchstaben gleich viel Platz im Dokument zuweist.

Listing 2

label-format

01 #!/usr/local/bin/perl -w
02 use strict;
03 use PDF::Create;
04 use Encode qw( _utf8_on );
05
06 my( $string ) = @ARGV;
07 _utf8_on( $string );
08
09 die "usage: $0 string" if !defined $string;
10
11 my $pdf = PDF::Create->new(
12   filename => 'label.pdf' );
13
14 my $width     = 144;
15 my $height    = 54;
16 my $font_size = 20 / length( $string ) * 11;
17 my $adjust    = $font_size/7;
18
19 my $page = $pdf->new_page(
20  'MediaBox' => [ 0, 0, $width, $height ] );
21
22 my $f1 = $pdf->font(
23   Subtype  => 'Type1',
24   Encoding => 'WinAnsiEncoding',
25   BaseFont => 'Helvetica'
26 );
27
28 $page->stringc( $f1,
29   $font_size,
30   $width/2 + 10,
31   ($height - $font_size)/2 + $adjust,
32   $string );
33
34 $pdf->close;
35
36 system( "acroread label.pdf" );

Die in Zeile 28 aufgerufene Methode »stringc()« platziert den als viertes Argument angegebenen String in die Mitte des PDF-Dokuments. Die Fontgröße kommt als zweiter Parameter herein, gefolgt von den x- und y-Koordinaten der Stringmitte. Der x-Wert läuft vom linken Rand des Dokuments nach rechts, der y-Wert vom unteren Rand nach oben. Aus unerklärlichen Gründen befand sich bei mir der Textstring aber immer zu weit unten im Dokument, sodass ich die Variable »$adjust« in Zeile 17 ins Leben gerufen habe, um den String um ein Siebtel der Fontgröße nach oben zu schieben.

Mit diesen einfachen Tricks positioniert der Etikettendrucker sowohl kurze als auch etwas längere Textzeilen bis zu etwa 25 Zeichen optimal in der Dokumentmitte, der Aufruf von »cmd-print« wirft den Drucker an, und das Etikett kommt herausgeschossen.

Die Verarbeitung von Umlauten ist etwas speziell. Da der von der Kommandozeile hereingereichte String bereits in UTF-8 kodiert ist, Perl ihn aber in der Standardeinstellung als Ascii interpretiert, kämen ohne spezielle Verarbeitung statt Umlauten kryptische Zeichen aus dem Drucker. Die Funktion »_utf8_on« aus dem Modul Encode teilt dem Interpreter mit, dass es sich bei dem hereingereichten String ja bereits um UTF-8 handelt, also die Umkodierung entfällt.

Das CPAN-Modul zum Erzeugen von PDFs kann aber nicht nur Strings auf weißem Hintergrund ablegen, sondern auch Bilder positionieren. Bei einem Thermodrucker, der nur schwarz-weiß ohne Grautöne kann, sind die Möglichkeiten in dieser Hinsicht natürlich beschränkt, aber wie wäre es mit selbstklebenden Etiketten, auf denen ein Barcode prangt?

Listing 3

dymo-qr

01 #!/usr/local/bin/perl -w
02 use strict;
03 use Image::PNG::QRCode 'qrpng';
04 use Graphics::Magick;
05 use File::Temp qw( tempfile );
06 use PDF::Create;
07
08 my( $text ) = @ARGV;
09 die "usage: $0 text" if !defined $text;
10
11 my $width     = 144;
12 my $height    = 54;
13 my $pdffile   = "label.pdf";
14
15 my( $fh, $pngfile ) =
16   tempfile( UNLINK => 1,
17             SUFFIX => ".png" );
18
19 ( my $jpgfile = $pngfile ) =~
20   s/\.png$/.jpg/;
21
22 qrpng ( text => $text,
23         out  => $pngfile );
24
25 my $img = Graphics::Magick->new;
26 $img->Read( $pngfile );
27 $img->Write( $jpgfile );
28
29 my $pdf = PDF::Create->new(
30   filename => $pdffile );
31
32 my $jpg = $pdf->image( $jpgfile );
33
34 my $page = $pdf->new_page(
35  'MediaBox' => [ 0, 0, $width, $height ] );
36
37 $page->image( 'image' => $jpg,
38     'xscale' => 0.5, 'yscale' => 0.5,
39     'xpos'   => 50,  'ypos'   => 0 );
40
41 $pdf->close;

QR-Codes lassen sich mit Smartphones scannen. Damit ließen sich Inventarnummern an Geräte vergeben, die man als Etikett mit QR-Code aufklebt, bei Bedarf einscannt und unter der Assetnummer in einer Datenbank oder einem Merksystem wie Evernote stöbert, etwa nach der eingescannten Bedienungsanleitung. Listing 3 baut aus dem ihm auf der Kommandozeile übergebenen Text mit dem CPAN-Modul Image::PNG::QRCode den in Abbildung 6 sichtbaren QR-Barcode:

dymo-qr "Hallo, Linux-Magazin!"

Eine der freien QR-Scanner-Apps (QR Reader auf einem iPhone) erkennt den QR-Code auf dem Etikett, das noch im Drucker steckt und noch nicht einmal abgetrennt wurde. Abbildung 7 präsentiert den schlichten Text.

Abbildung 6: Das Scanprogramm sucht den QR-Code im Foto …
Abbildung 7: … erkennt ihn und gibt den einkodierten Text aus.

Da das benutzte CPAN-Modul zum Generieren des QR-Codes aber nur Bilder im PNG-Format schreiben kann, holt Listing 3 auch noch einen Klon des CPAN-Moduls Image::Magick zum einfachen Konvertieren von Bildformaten herein. Das Modul lässt sich allerdings nicht ohne zusätzliche Handarbeit installieren, weil es allerlei Entwicklungspakete diverser Libraries beansprucht. Aber zum Glück hat sich ein Engel aus dem Hause Ubuntu erbarmt und mit »perlmagick« ein Paket erzeugt, das mit dem Modul Graphics::Magick die gleichen Funktionen bereitstellt.

Die mit »File::Temp« verwaltete temporäre PNG-Datei wandelt das Modul in eine Jpg-Datei um, die wiederum »PDF::Create« aufschnappt und in ein PDF-Dokument einbaut. Das so erzeugte »label.pdf« schiebt Listing 1 wie gewohnt zum Etikettendrucker weiter.

Der einzige Nachteil meines Etikettendruckers ist, dass es dafür keine stabilen Plastiketiketten gibt. Nur schwarzer Thermodruck auf weißem Papier oder durchsichtiger Folie, beides selbstklebend, ist möglich. Ein weiteres Druckermodell, der teurere Labelwriter Duo, scheint mehr Optionen zu bieten. Vielleicht ergibt sich bald die Gelegenheit, ein Schnäppchen zu machen.

Infos

  1. Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2015/12/Perl
  2. Linux-SDK für den Etikettendrucker: http://var.dymo.com/US/resources/sdk/linux/
  3. Michael Sweet, "CUPS: Common UNIX Printing System": Sams Publishing, September 7, 2001

Der Autor

Michael Schilli arbeitet als Software Engineer in der San Francisco Bay Area in Kalifornien. In seiner seit 1997 laufenden Kolumne forscht er jeden Monat nach praktischen Anwendungen der Skriptsprache Perl. Unter mailto:mschilli@perlmeister.com beantwortet er gerne Fragen.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Perl-Snapshot

    Etiketten bringen Ordnung in den Kabelverhau am Heim-Router und helfen beim Zuordnen von in Kisten gelagertem Plunder. Mit einigen Handgriffen druckt Michael Schillis Labelwriter sogar unter Linux. Im Video zeigt er, wie das funktioniert.

  • Perl-Snapshot

    Open Office hilft mit einer Vielzahl vorkonfigurierter Formate beim Ausdrucken von selbstklebenden Etiketten. Perl speist die dazu erforderlichen Adressdaten ins Dokument ein.

comments powered by Disqus

Ausgabe 10/2016

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.