Producing stickers and QR codes on a label printer with Perl
Label Maker
Labels bring order to the mess of wires hiding behind the Perlmeister's home routers and organize the treasures hoarded in a multitude of boxes. With just some tweaking, the Dymo LabelWriter even prints on Linux.
For decades, I have organized my network cables with permanent labels (Figure 1) printed on a portable device by Brother. However, it bugs me that every time I print a label the device wastes raw material (Figure 2), which I have to buy in the form of fairly expensive cartridges.
Brother's engineers deliberately seem to have built the machine to use twice as much label ribbon as I actually need, boosting the ribbon cartridge turnover as a side effect! If there is a hell for committing such wanton waste, I expect that the product managers responsible for this feature will be there some time soon. Apart from this, typing strings like 192.168.0.1 takes ages on the unorthodox keyboard; using a desktop computer would be far quicker.
Faster than Manual
Recently, I found a label printer on eBay that I was able to connect with my Ubuntu desktop via a USB port. The LabelWriter 450 Turbo by Dymo (Figure 3) cost me around $40 secondhand, and I got it working in no time. What you need is the printer's CUPS system driver, which is available as source code [1].
After installing a couple of additional packages, such as libcups2-dev
and libcupsimage2-dev
, with apt-get
, I was able to complete the build using ./configure; make
without any trouble. Then, sudo make install
installed the CUPS files. It wasn't until later that I discovered that my Ubuntu distribution has an easy-to-install package and that
sudo apt-get install printer-driver-dymo
would do the job in one fell swoop.
After installing the CUPS drivers, Ubuntu detected the new label printer without much ado. A call to
lpstat -p -d
shows the available printers and their states (e.g., printer LabelWriter-450-Turbo is idle). If you are interested in the label sizes the driver supports, you can type
lpoptions -p LabelWriter-450-Turbo -l
to query them. Below Printers in the system settings, you should see a dialog like that in Figure 4 with a Printer Options submenu, in which you can configure the dimensions of the labels you are using.
I bought a roll of labels numbered "30330" featuring 500 return address labels. I wasn't really worried about what professional shippers use these labels for; it was the handy 19x51mm format that interested me.
The labels are shot vertically out of the thermo-printer, so I needed to adjust the lettering to match; in other words, rotated through 90 degrees in landscape. Now, how does the computer actually send the text to be printed to the device?
The CUPS printing system [2] uses the lpr
command for this:
lpr -P LabelWriter-450-Turbo -o PageSize=w54h144.1 label.pdf
As you can see, the option -P LabelWriter-450-Turbo
tells CUPS to select the label printer if some other device is configured as the default printer. The label dimensions are set using the PageSize
option, which expects the length and width – not in millimeters or inches, but in points.
Some brief research on Google showed that you need to multiply millimeters by around 1.8 to convert to points (Figure 5). To match the 19x51mm labels, I thus needed rectangles in a format of 54x144.1 points; the parameter I used – PageSize= w54h144.1
– defined precisely that size.
The final argument the lpr
command expects is the name of the PDF file with the text to be printed.
Formatting as PDF
Listing 1 [3] generates the required print layout with the help of the CPAN PDF::Create module. The script expects a string at the command line, for example,
label-format "Huzzah!"
and dumps it into the middle of a PDF document in landscape format measuring 144.1x54 points. Note that the text needs to be quoted if it contains blanks. Some shell dialects also expect you to quote the exclamation marks, which the shell would otherwise interpret as a call to its history function. Looking at the code, the reasoning behind the expression
in line 16 of Listing 1 is that my experiments revealed that a string of eleven 20-point characters would precisely fill out the label lengthwise. Longer strings necessitate a linear font size reduction to fit on the label. This simple formula works amazingly well even though the Helvetica font I chose does not use fixed-width spacing but assigns a proportional amount of space to each letter in the document.
Listing 1
label-format
The stringc()
method called in line 28 prints the string passed in as its fifth argument in the middle of the PDF document. The font size is the second parameter, followed by the x and y coordinates of the center of the label. The x value runs from left to right in the document, and the y value from the bottom to the top edge. For some strange reason, the text string was always too low in the document in my experiments; this prompted me to introduce the $adjust
variable in line 17 to move the string upward by one seventh of the font size.
Thanks to these simple tricks, the label printer positions both short and slightly longer lines of text with up to 25 characters perfectly at the center of the document; the call to cmd-print
fires up the printer, and the label comes flying out.
The process for handling non-standard characters, like umlauts, is something special. Because the string passed in at the command line is already UTF-8 encoded, but Perl interprets it as ASCII by default, you would normally see the printer output cryptic characters rather than what you wanted if left to its own devices. The _utf8_on
function from the Encode module tells the interpreter that the string you passed in is already UTF-8 encoded and that there is thus no need to recode.
The CPAN module for creating PDFs can do more than just position strings on a white background; it can also position images. Of course, a thermal printer that can only print black without grayscale limits your artistic options somewhat, but what about printing sticky labels with barcode?
You can scan QR codes with a smartphone, opening up the option of assigning inventory numbers to devices printed as QR codes on labels that you could then scan and, if needed, store next to an asset number in a database or a filing system like Evernote, say, for a scanned owner's manual.
Listing 2 processes the text passed in at the command line,
dymo-qr "Linux Pro Magazine!"
and uses the CPAN Image::PNG::QRCode module to generate the QR code shown in Figure 6. The free QR Reader iPhone scanner app detected the QR code on the label still in the printer, even without me tearing off the label. Figure 7 shows the plain text version in the app.
Because the CPAN module I used to generate the QR code can only output PNG-formatted images, Listing 2 uses a clone of the CPAN Image::Magick module as an easy option for converting image formats. Installing the module involves some manual attention because it needs a number of developer packages from various libraries. Fortunately, a kind person from Ubuntu went through the trouble of generating a perlmagick
package that provides the feature set with the Graphics::Magick module.
Listing 2
dymo-qr
The module converts the temporary PNG file managed using the File::Temp module into a JPG file, which is then picked up by PDF::Create and dumped into a PDF document. The label.pdf
file that this process creates is then forwarded to the label printer with the previously shown lpr
command.
The only disadvantage with my label printer is that you can't buy rugged plastic labels for it. It only does black thermal printing on white paper or transparent film, both of which are self-adhesive. That said, however, the more expensive printer model called LabelWriter Duo, seems to have more options. I might just go bargain hunting again in the near future.
Infos
- Linux SDK for the label printer: http://var.dymo.com/US/resources/sdk/linux/
- Sweet, Michael. CUPS: Common UNIX Printing System. Sams Publishing, 2001.
- Code for this article: ftp://ftp.linux-magazine.com/pub/listings/magazine/183/
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.
-
VirtualBox 7.1.4 Includes Initial Support for Linux kernel 6.12
The latest version of VirtualBox has arrived and it not only adds initial support for kernel 6.12 but another feature that will make using the virtual machine tool much easier.