Convert PBM Images to Epson Printer Streams with pbmtoepson
pbmtoepson turns a PBM bitmap into Epson printer control data you can inspect before you trust it near an actual printer. The examples use Netpbm 11.5.2 from package netpbm 2:11.05.02-1.1build1 on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a readable PBM file and the Netpbm tools. A printer is optional for this guide. Keep the first output in an ordinary file: printer streams are binary control data, not an image format you can sensibly inspect in a text editor.
1. Check the installed command
Confirm the command is installed and record the version before trusting any example. These are read-only commands, no elevated privileges needed:
$ command -v pbmtoepson
/usr/bin/pbmtoepson
$ pbmtoepson --version
pbmtoepson: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The installed manual describes four command-specific controls: -protocol=escp9 or -protocol=escp, -dpi=n, -adjacent, and -nonadjacent. Netpbm also accepts common libnetpbm options such as -quiet, using a single hyphen throughout.
Checkpoint
Stop here if command -v finds nothing. Install Netpbm through your normal package-management process and repeat the check, rather than guessing at a location.
2. Prepare a small PBM test
Use a tiny monochrome PBM for checking the pipeline. Plain PBM syntax is portable enough to pipe through standard input with no source file at all:
$ printf 'P1\n8 8\n0 0 1 1 1 1 0 0\n0 1 0 0 0 0 1 0\n1 0 1 0 0 1 0 1\n1 1 1 1 1 1 1 1\n1 1 1 1 1 1 1 1\n1 0 1 0 0 1 0 1\n0 1 0 0 0 0 1 0\n0 0 1 1 1 1 0 0\n' > /tmp/test-pattern.pbm
That's temporary test data under /tmp. For a real image, swap in the PBM file you already have, and don't assume a bitmap-looking extension means PBM: check with file if you're unsure:
$ file /path/to/input.pbm
/path/to/input.pbm: Netpbm image data, size 8 x 8, ASCII bitmap
The exact wording varies with the PBM variant. What matters is that it's identified as Netpbm bitmap data and is readable.
3. Convert to a file first
Run the converter with explicit settings and redirect standard output to a file. This example picks the newer ESC/P protocol at 60 dots per inch:
$ pbmtoepson -protocol=escp -dpi=60 /tmp/test-pattern.pbm > /tmp/test-pattern.escp
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ wc -c /tmp/test-pattern.escp
20 /tmp/test-pattern.escp
pbmtoepson reads the named PBM file and writes Epson graphics to standard output; omit the filename and it reads standard input instead. The output is not a PBM, PDF or ordinary raster file, it's a printer stream of control bytes and image data.
Safety boundary
Do not redirect an untested command straight to a device such as /dev/usb/lp0. That can print immediately, burn paper and alter printer state. The file conversion above is ordinary user work; accessing a printer device may need device-group membership or elevated privileges, but sudo does not make an incompatible protocol safe.
4. Inspect and verify the stream
Check the output is non-empty and begins with plausible Epson control bytes. This is not a full printer compatibility test:
$ xxd -g1 -l 32 /tmp/test-pattern.escp
00000000: 1b 41 08 1b 2a 00 08 00 3c 5a bd 99 99 bd 5a 3c .A..*...<Z....Z<
00000010: 0a 0c 1b 40 ...@
$ test -s /tmp/test-pattern.escp && echo 'stream is non-empty'
stream is non-empty
Your bytes will change with the input image, protocol, density and dot-printing mode. A zero exit status means the conversion completed, not that a particular Epson model will accept the stream.
For a pipeline, the equivalent form is:
$ pbmtoepson -protocol=escp -dpi=60 < /path/to/input.pbm > /tmp/output.escp
Standard input is handy in scripts, but it hides the source when you come back to the command later, so prefer a named input file while diagnosing a failed conversion.
5. Choose protocol and density deliberately
Use -protocol=escp9 for the older ESC/P 9-pin protocol or -protocol=escp for the newer ESC/P protocol. The manual points modern ESC/P2 printers to the separate pbmtoescp2 program instead. Don't pick escp just because the printer is an Epson: check the model's own protocol documentation.
The accepted -dpi values are exactly 60, 72, 80, 90, 120, 144 and 240, controlling horizontal print density:
$ pbmtoepson -protocol=escp9 -dpi=120 /path/to/input.pbm > /tmp/output-escp9.120dpi
Omit -dpi and the program picks a density consistent with your other options, which is convenient but less reproducible in a script. An unsupported value fails outright before anything useful gets produced:
$ pbmtoepson -dpi=61 /path/to/input.pbm > /tmp/invalid.escp
pbmtoepson: Invalid DPI value: 61. This program knows only 60, 72, 80, 90, 120, 144, and 240.
Leave -adjacent and -nonadjacent unset for a first test. The program defaults to adjacent dot printing unless that clashes with your other choices. Add one only when the printer or the appearance of the output actually gives you a reason to, and never use both together.
6. Recover from common failures
A non-zero exit status usually points to an unreadable or invalid PBM, an unsupported density, or a bad option. Read the diagnostic before reaching for permissions changes or sudo:
$ test -r /path/to/input.pbm && echo readable
$ pbmtoepson -dpi=240 /path/to/input.pbm > /tmp/output.escp
$ printf 'exit status: %s\n' "$?"
If the output is wrong for the printer, keep the PBM and remove only the generated stream, after checking nothing else is using it:
$ rm /tmp/output.escp
Warning
That removes a derived temporary file, not the source image; never delete the original PBM to fix a conversion problem. If you've already sent a stream to a printer, stop the job through that printer's normal queue controls. pbmtoepson itself has no reverse-conversion command and cannot retract paper that's already printed.
Done means
- Version and input confirmed. You checked the installed Netpbm version and the PBM input type.
- File before printer. You converted to a file before considering printer output.
- Settings deliberate. You used a supported protocol and, where reproducibility mattered, an explicit density.
- Result verified. You checked the exit status and confirmed the stream is non-empty.
- Right protocol. You matched ESC/P, ESC/P 9-pin or ESC/P2 to the printer's own documentation.
- Source preserved. The PBM is intact, and you know how to remove only a disposable derived stream.