Send a PBM Image to an ESC/P2 Printer with pbmtoescp2
pbmtoescp2 turns a PBM bitmap into an ESC/P2 printer control stream you save first and inspect, rather than firing blind at an Epson printer. Allow fifteen minutes for a first conversion, plus time to confirm the image dimensions suit the paper.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses the pbmtoescp2 shipped in Netpbm package version 2:11.05.02-1.1build1. You need a PBM file and an Epson printer that understands ESC/P2. The command doesn't talk to the printer itself: it writes a binary stream to standard output, which you save or hand to a separate printing workflow.
1. Check the installed command
Confirm the executable is available. This is an ordinary read-only check, no elevated privileges needed:
$ command -v pbmtoescp2
/usr/bin/pbmtoescp2
$ dpkg-query -W -f='\${Package} \${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The installed help output just points to the manual page rather than listing options. Read that page when checking a host with a different Netpbm version:
$ pbmtoescp2 --help
pbmtoescp2: Use 'man pbmtoescp2' for help.
Checkpoint
If command -v finds nothing, install Netpbm through your normal package-management process, rather than copying a binary over from an unrelated host.
2. Check the PBM dimensions
Each input pixel becomes one printed dot. PBM has no inherent resolution, so the -resolution option describes how densely those pixels print. Inspect the image before choosing settings:
$ file /path/to/image.pbm
/path/to/image.pbm: Netpbm image data, size 1440 x 1800, bitmap, ASCII text
$ head -n 3 /path/to/image.pbm
P1
1440 1800
...
For example, a 1440 by 1800 bitmap at 180 dpi is 8 by 10 inches; the same pixel count at 360 dpi is 4 by 5 inches. If the physical size is wrong, resize the PBM with a suitable Netpbm tool first: don't expect pbmtoescp2 to resize it for you.
3. Convert a PBM to a printer stream
Save standard output to a new file. The defaults are 360 dpi, RLE compression, and a stripe height of 24 lines:
$ pbmtoescp2 /path/to/image.pbm > /path/to/image-escp2.bin
$ wc -c /path/to/image-escp2.bin
123456 /path/to/image-escp2.bin
The byte count depends on the image and compression, but should be greater than zero. Don't run the command without redirection on an interactive terminal: the result is binary control data, not readable text.
Input can also come from standard input, useful in a pipeline, but keep the output redirection visible so the stream doesn't just vanish into the terminal:
$ cat /path/to/image.pbm | pbmtoescp2 > /path/to/image-escp2.bin
$ test -s /path/to/image-escp2.bin && echo 'non-empty ESC/P2 stream'
non-empty ESC/P2 stream
No need for sudo when reading an image and writing to a directory you own. Reach for elevated privileges only if a later, separate printing command genuinely needs access to a protected device or spooler.
4. Choose resolution and compression deliberately
Valid resolutions are 180, 360 and 720 dpi, setting both horizontal and vertical resolution in the stream. The default of 360 is not a measurement read from the PBM:
$ pbmtoescp2 -resolution=180 /path/to/image.pbm > /path/to/image-180dpi.bin
$ wc -c /path/to/image-180dpi.bin
123456 /path/to/image-180dpi.bin
- RLE compression is on by default with
-compress=1, and works well for line drawings, text and other repeated horizontal patterns. - Photograph-like bitmap compressing badly? Use
-compress=0for uncompressed raster data and compare the resulting file size.
$ pbmtoescp2 -compress=0 -resolution=180 /path/to/image.pbm > /path/to/image-180dpi-raw.bin
$ wc -c /path/to/image-180dpi-raw.bin
234567 /path/to/image-180dpi-raw.bin
Those numbers illustrate the shape of the output, not expected sizes. Keep the smaller stream only if the printer accepts that mode and the printed result is actually correct.
5. Adjust stripe handling when the printer needs it
Raster data comes out in vertical stripes, 24 lines high by default. The printer language has standard heights of 1, 8 and 24, though the command accepts 1 to 255 and warns for anything else:
$ pbmtoescp2 -stripeheight=8 /path/to/image.pbm > /path/to/image-stripe8.bin
$ test -s /path/to/image-stripe8.bin && echo 'stripe-8 stream written'
stripe-8 stream written
Use this for a documented printer or integration requirement, not as a general quality knob. A stripe height of 8 doesn't change the input dimensions; the output pads vertically to the stripe boundary and horizontally to a multiple of eight columns. Current Netpbm releases preserve the image through that padding; releases before 10.72 truncated at those boundaries instead.
6. Add a form feed or generate raw blocks only
-formfeed adds a form-feed command at the end of the output, for when the receiving workflow expects the stream to finish the page:
$ pbmtoescp2 -formfeed /path/to/image.pbm > /path/to/image-with-formfeed.bin
-raw does something different: it omits the printer setup commands and emits only data blocks, for inserting raster data into a larger command stream that already sets up the printer. Don't use it as the normal standalone conversion:
$ pbmtoescp2 -raw /path/to/image.pbm > /path/to/image-data-blocks.bin
These options change the protocol stream, not the PBM itself. Leave -raw out if you need a complete standalone file.
7. Check failures before retrying
An invalid resolution gets rejected rather than guessed at:
$ pbmtoescp2 -resolution=300 /path/to/image.pbm > /tmp/should-not-be-used.bin
pbmtoescp2: Invalid -resolution value: 300. Only 180, 360 and 720 are valid.
Check the exit status immediately after a conversion, especially in a script:
if pbmtoescp2 -resolution=360 /path/to/image.pbm > /path/to/image-escp2.bin; then
test -s /path/to/image-escp2.bin || exit 1
printf '%s\n' 'ESC/P2 stream ready'
else
status=$?
printf 'conversion failed with status %s\n' "$status" >&2
exit "$status"
fi
Shell redirection truncates an existing destination before the program even starts. To protect a useful output, write a temporary file in the same directory and rename it only after success:
tmp='/path/to/image-escp2.bin.new'
pbmtoescp2 /path/to/image.pbm > "$tmp" && test -s "$tmp" && mv -- "$tmp" /path/to/image-escp2.bin
If conversion fails, the old destination stays in place, but the temporary file may be incomplete and should be removed after checking it. The mv is the step that actually changes the destination, so keep a backup if the existing stream would be hard to recreate.
Done means
- Version and path checked. The installed Netpbm version and
pbmtoescp2path were confirmed. - Physical size right. The PBM dimensions match the intended size at the selected dpi.
- Stream saved, not displayed. A non-empty ESC/P2 stream went to a file rather than the terminal.
- Options chosen for a reason. Compression, stripe height, form feed and raw mode were each set deliberately.
- Result verified. Exit status and output size were checked, and nothing existing was overwritten accidentally.
- Right destination. The stream only goes to an Epson printer or workflow that actually supports ESC/P2.