Home / Alt manpages / pgmdeshadow(1)

  • pgmdeshadow(1)
  • User command
  • linux

Remove Page Shadows from Scanned PGM Images with pgmdeshadow

You will reduce a smooth grey shadow in a scanned PGM image and write a checked, separate output file. This is useful for pages with a darker strip near the binding or along an outer edge. Allow about ten minutes for one image. You need the Netpbm package, a readable PGM file, and enough free space for another copy of the image.

The examples use Netpbm 11.5.2, provided here by Debian package netpbm version 2:11.05.02-1.1build1. Your release may behave differently in details not covered by this guide, so check its local manual page with man 1 pgmdeshadow.

1. Check the input and installed version

Start by confirming that the executable is available and that the source is readable. These commands do not alter the image:

$ command -v pgmdeshadow
/usr/bin/pgmdeshadow
$ pgmdeshadow --version
pgmdeshadow: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...
$ file /path/to/page.pgm
/path/to/page.pgm: Netpbm image data, size 2480 x 3508, rawbits, greymap

The version probe prints build information and exits; the installed program directs you to its manual page for help. The file result should identify a Netpbm greymap. If the path contains spaces, quote it in every command.

2. Preserve the original before processing

pgmdeshadow reads a PGM image and writes the processed image to standard output. Keep the source unchanged and choose a new destination. Do not redirect straight back to the input path: the shell truncates the destination before the program has read the complete source.

$ cp --preserve=all /path/to/page.pgm /path/to/page.pgm.bak
$ pgmdeshadow /path/to/page.pgm > /path/to/page-deshadowed.pgm

The copy is a precaution rather than a requirement for the command. The conversion itself needs no elevated privileges when both files are in a directory you can write. Do not use sudo to compensate for an unclear destination or input path.

Checkpoint: the command should return to the shell without a progress display. Confirm that the new file exists and is non-empty:

$ test -s /path/to/page-deshadowed.pgm && echo 'output is non-empty'
output is non-empty
$ file /path/to/page-deshadowed.pgm
/path/to/page-deshadowed.pgm: Netpbm image data, size 2480 x 3508, rawbits, greymap

3. Use standard input when that fits a pipeline

The input filename is optional. With no filename, the program can read a PGM stream from standard input, which is handy when another tool produces a PGM. The output remains standard output:

$ cat /path/to/page.pgm | pgmdeshadow > /path/to/page-deshadowed.pgm

For a plain file, passing the filename is easier to review and gives clearer errors. Either form leaves the source file alone. Avoid adding unrelated filters until the direct conversion has been checked; a pipeline can hide which command failed unless you configure shell pipeline error handling.

4. Understand what the filter is correcting

The program is designed for grey shadows that change smoothly from an outside edge of the image, such as the darker area beside a book crease. It estimates a local shadow level and adjusts each pixel against that level. It is not a general-purpose image editor and it does not remove arbitrary marks, text bleed, stains or sharply defined objects.

There are no pgmdeshadow-specific command-line options. The manual says that it accepts options common to libnetpbm programs, but this guide does not add undocumented switches. In particular, the command does not take a width or height argument for this operation. The input image supplies those dimensions, and the output from the test above retained 2480 by 3508 pixels.

PGM is a greyscale format. If your scan is PNG, JPEG or a colour PPM, convert it to a suitable greyscale PGM with an appropriate Netpbm or image-processing tool first, then run this command. Keep that conversion as a separate step so you can verify each file format.

5. Verify the result before replacing anything

A successful exit status confirms that the command completed, not that the page looks correct. Check the format and dimensions, then open the result in an image viewer or pass it to a trusted converter:

$ file /path/to/page-deshadowed.pgm
/path/to/page-deshadowed.pgm: Netpbm image data, size 2480 x 3508, rawbits, greymap
$ cmp --silent /path/to/page.pgm /path/to/page-deshadowed.pgm
$ printf '%s\n' "$?"
1

The cmp status of 1 is expected for an image that has changed; it is not a quality score. If it returns 0, the two files are byte-for-byte identical and the shadow correction did not change this input. To inspect the page after converting it to a viewer-friendly format, use a separate installed command such as pnmtopng if available:

$ pnmtopng /path/to/page-deshadowed.pgm > /path/to/page-deshadowed.png
$ file /path/to/page-deshadowed.png
/path/to/page-deshadowed.png: PNG image data, 2480 x 3508, 8-bit grayscale, non-interlaced

6. Handle failures without losing the source

If the command cannot open the input, inspect the path and permissions without changing them:

$ ls -l /path/to/page.pgm
$ test -r /path/to/page.pgm && echo readable

If the output is missing or has a zero size, stop and keep the original. A failed redirection can leave an incomplete destination, so remove or quarantine only that newly named output after checking its path. Do not delete the source or its backup as part of recovery.

If the result is technically valid but visually worse, return to page.pgm or page.pgm.bak. There is no in-place undo inside pgmdeshadow. Once you have accepted the new image, you can rename it deliberately, but do not overwrite the original until the visual check is complete.

Done means

  • pgmdeshadow is installed and its Netpbm version is known.
  • The source is a readable PGM greymap and remains unchanged.
  • The command wrote a separate, non-empty PGM output with the expected dimensions.
  • You checked the result visually or with a later image conversion before accepting it.
  • A failed or disappointing run can be abandoned by keeping the original and its backup.