Turn ASCII Shading into a PGM Image with asciitopgm
asciitopgm turns a block of plain-text shading into a real greyscale PGM image, character by character. It is one of the oldest Netpbm converters, and its height-then-width argument order still catches people out. Allow about ten minutes. You need a shell, the netpbm package, and an ASCII input whose intended height and width you already know.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Check the installed command
This guide follows Netpbm 11.5.2, installed here as Debian package version 2:11.05.02-1.1build1. The local manual page is dated 20 January 2011, so treat the examples as a description of this installed command, not a promise about every Netpbm release.
$ command -v asciitopgm
/usr/bin/asciitopgm
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The command takes the output height first, then the output width, then an optional input file:
asciitopgm [-d divisor] height width [asciifile]
That order is an easy trap. asciitopgm 3 4 means three rows high and four columns wide, not four rows high and three columns wide.
2. Make a small input with an explicit size
Work in a new directory so the input and the generated image are easy to tell apart. This is an ordinary shell operation and needs no elevated privileges:
$ mkdir -p ~/asciitopgm-example
$ cd ~/asciitopgm-example
$ printf 'M. \n .# \n \n' > drawing.txt
$ wc -l -L drawing.txt
3 4 drawing.txt
- Three lines, four characters each. That matches the height and width you will pass to the command.
- The trailing spaces matter. A space represents white, and a missing character is padded with white too.
- Avoid editors that trim trailing whitespace. If they strip the spaces, they strip part of the drawing.
Checkpoint
Inspect invisible line endings and trailing spaces before converting.
$ sed -n 'l' drawing.txt
M. $
.# $
$
3. Convert the drawing to PGM
Redirect standard output to a new file. asciitopgm reads the input as ASCII text and assigns a greyscale value based on an assumed printing font: a capital M comes out dark, a full stop lighter, a space white. That is an approximation, not a font renderer.
$ asciitopgm 3 4 drawing.txt > drawing.pgm
$ file drawing.pgm
drawing.pgm: Netpbm image data, size = 4 x 3, rawbits, greymap
$ head -n 3 drawing.pgm
P5
4 3
127
The header confirms width 4 and height 3, with a maximum sample value of 127 for this command's output. The rest of the file is binary pixel data, so do not open the whole thing in a text editor.
None of this needs sudo. If the command fails, check that you can read the input and write the output in a directory you own, and keep the original text file until you have checked the image.
4. Tune the character darkness
Reach for -d with an integer divisor when the result is too light or too dark. The default is 1. The manual says the value divides character blackness and that larger values darken the output, but the safest check is a small trial conversion rather than guessing from the option name.
$ asciitopgm -d 2 3 4 drawing.txt > drawing-dark.pgm
$ file drawing-dark.pgm
drawing-dark.pgm: Netpbm image data, size = 4 x 3, rawbits, greymap
Use a positive integer such as 2 or 4, and keep the height and width the same while you compare files. Changing either dimension changes how many output samples get written; it is not a brightness control.
Checkpoint
Compare the headers before you open the images.
$ head -n 3 drawing.pgm
P5
4 3
127
$ head -n 3 drawing-dark.pgm
P5
4 3
127
5. Use standard input or overstrike rows
Leave out the input filename and asciitopgm reads from standard input instead, which is handy in a pipeline. Keep the dimensions explicit even so:
$ printf 'AB\n' | asciitopgm 1 3 > piped.pgm
$ head -n 3 piped.pgm
P5
3 1
127
- Short lines get padded. Anything narrower than the requested width is padded with white.
- Long lines get truncated. Extra characters past the requested width are dropped.
- Extra rows are ignored. Input taller than the requested height simply loses its spare lines.
A successful exit status does not prove the dimensions you gave were the right ones. A line starting with + is a special case: instead of a new row, asciitopgm merges the rest of that line with the previous row, which can produce a wider range of greys. There is no previous row at the very start of the input, so only use + after an ordinary row.
6. Handle input warnings and failed replacements
asciitopgm reads only the lower seven bits of each input byte, and warns when a byte has its top bit set. It is built for ASCII, not UTF-8 artwork; if you hit that warning, check the file's encoding rather than trusting accented or non-Latin characters to give you reliable shades.
Shell redirection truncates an existing destination before the converter even runs. Protect a useful image by writing to a temporary name, checking it, then swapping it in:
$ asciitopgm 3 4 drawing.txt > drawing.pgm.new
$ file drawing.pgm.new
drawing.pgm.new: Netpbm image data, size = 4 x 3, rawbits, greymap
$ mv drawing.pgm.new drawing.pgm
If the conversion fails, leave drawing.pgm alone and remove the incomplete drawing.pgm.new once you have read the error. Run mv only after the replacement has the dimensions you expected.
Done means
- The installed Netpbm version and
asciitopgmpath are known. - The input is ASCII, with intentional trailing spaces preserved.
- Height and width were supplied in the documented order.
- The PGM header reports the expected width and height.
- Brightness changes used
-dwhile keeping dimensions constant. - The original text remains available, and replacement output was checked before it was moved into place.