Home / Alt manpages / ppmtv(1)

  • ppmtv(1)
  • User command
  • linux

Add Scanline Dimming to a PPM Image with ppmtv

You will finish with a PPM image whose alternate rows are dimmed by a chosen factor. This produces a simple scanline-style television effect while leaving the source image untouched. The examples use the installed Netpbm package, version 2:11.05.02-1.1build1, which provides Netpbm 11.5.2 on this machine.

Allow about ten minutes. You need ppmtv, a readable PPM image, and enough space for a second copy of the image. The normal workflow is unprivileged. Do not use sudo: this command reads an image and writes its result to standard output, so elevated access does not improve the conversion.

1. Check the installed command

Confirm which executable will run and record the package version before relying on examples in a script:

$ command -v ppmtv
/usr/bin/ppmtv
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
$ ppmtv --version
ppmtv: Using libnetpbm from Netpbm Version: Netpbm 11.5.2

The version diagnostic includes build details after the version line on this installation. Do not treat the extra lines as part of the image output. The command's manual is the useful interface reference, and says that the program accepts one required dimension factor followed by an optional input filename.

Checkpoint

Proceed only if command -v points at the Netpbm program you intend to use. If it is missing, stop and install Netpbm through your normal package-management process rather than copying an unverified binary into a working directory.

2. Choose a dimming factor

The first argument controls the brightness of every other image row. It must be between 0.0 and 1.0. A factor of 0.0 makes the affected rows black. A factor of 1.0 leaves them at their original brightness. Values between those limits reduce the colour components proportionally.

For a visible but restrained effect, start with 0.5. The command does not resize the image, change its dimensions, or add a border. It changes alternate rows in the image data.

$ DIM_FACTOR=0.5
$ case "$DIM_FACTOR" in
  0|0.0|0.5|1|1.0) echo "factor selected: $DIM_FACTOR" ;;
  *) echo "choose a value from 0.0 to 1.0" >&2; exit 2 ;;
esac
factor selected: 0.5

The small shell check above only covers the values shown. If a script accepts arbitrary decimal input, validate it with the script's usual numeric handling and still let ppmtv reject values outside its documented range.

3. Render to a new file

Pass the input filename after the factor and redirect standard output to a new destination:

$ ppmtv "$DIM_FACTOR" /path/to/input.ppm > /path/to/output-scanlines.ppm

The optional filename is the input. If you omit it, ppmtv reads the PPM image from standard input, which is useful for a pipeline:

$ upstream-image-command | ppmtv 0.5 > /path/to/output-scanlines.ppm

Replace upstream-image-command with a real program that emits PPM. Do not paste that placeholder literally. The output is binary PPM on this installation, so terminal output will contain unreadable bytes. Always redirect it to a file or pipe it directly to a program that understands PPM.

Safety warning

Shell redirection with > truncates an existing destination before ppmtv starts. Never use the input path as the output path while experimenting. If a destination already contains something useful, choose a new name or make a backup first:

$ cp --preserve=all /path/to/output-scanlines.ppm /path/to/output-scanlines.ppm.bak
$ ppmtv 0.5 /path/to/input.ppm > /path/to/output-scanlines.ppm.new
$ mv /path/to/output-scanlines.ppm.new /path/to/output-scanlines.ppm

The temporary suffix keeps the previous output in place until the conversion has completed. If the command fails, remove only the incomplete .new file and retain the original. Once you have checked the replacement, the backup is optional; deleting it is irreversible, so do not include that deletion in an unattended test.

4. Verify the result as a PPM

Check that the output exists, is non-empty, and still has the source dimensions:

$ file /path/to/output-scanlines.ppm
/path/to/output-scanlines.ppm: Netpbm image data, size 1920 x 1080, rawbits, pixmap

Your dimensions and file wording will differ. The useful result is a PPM image with the expected width and height. On this system, ppmtv writes the raw PPM form identified by the P6 magic number. You can inspect only the header without dumping binary pixel data:

$ head -c 2 /path/to/output-scanlines.ppm
P6

Do not use a text editor to inspect the complete file. A PPM header is text, but the pixels after it are binary. If the file is empty or file does not recognise it as PPM, check the input path and the command's exit status before trying to view it.

For a visual check, open the new file with an image viewer that supports PPM, or convert it with another installed Netpbm tool. Conversion is a separate operation and is not required for ppmtv itself:

$ pnmtopng /path/to/output-scanlines.ppm > /path/to/output-scanlines.png
$ file /path/to/output-scanlines.png

If pnmtopng is not installed, keep the verified PPM or use the image tools already approved for your host. Do not discard the PPM until the later conversion or visual inspection has succeeded.

5. Test the factor boundaries safely

Use separate output names when checking the documented limits. The input remains unchanged, and the output dimensions should match each other:

$ ppmtv 0.0 /path/to/input.ppm > /tmp/input-black-rows.ppm
$ ppmtv 1.0 /path/to/input.ppm > /tmp/input-original-rows.ppm
$ file /tmp/input-black-rows.ppm /tmp/input-original-rows.ppm

At 0.0, alternate rows are totally black. At 1.0, those rows retain their original values, so the result should look like an unchanged copy apart from the normal PPM encoding details. The affected row parity is an implementation detail you should not infer from a single pixel: inspect a complete image with a regular viewer if the precise top-row pattern matters to your workflow.

These temporary files are safe to remove after checking them:

$ rm -- /tmp/input-black-rows.ppm /tmp/input-original-rows.ppm

That removal is destructive but limited to the two named test outputs. Keep the source image and any production output elsewhere. If you used the backup workflow, restore an earlier output only by explicitly moving or copying the backup back into place after checking its contents.

6. Diagnose rejected input

An out-of-range factor is rejected before a useful image is produced:

$ ppmtv 1.1 /path/to/input.ppm > /tmp/should-not-be-used.ppm
ppmtv: dim factor must be in the range from 0.0 to 1.0

The exact diagnostic can vary slightly with the Netpbm build. The remedy is to choose a value within the inclusive range, not to add sudo. Remove any zero-length or partial redirected file before reusing its name:

$ test -s /tmp/should-not-be-used.ppm || rm -- /tmp/should-not-be-used.ppm

If ppmtv cannot open the input, check the path and read permission without changing the file:

$ ls -l /path/to/input.ppm
$ test -r /path/to/input.ppm && echo readable

A successful exit status means the program processed the stream. It does not prove that the visual strength is suitable for publication or broadcast work. Check dimensions, open the result, and retain the source until the output has passed that review.

Done means

  • ppmtv is the expected Netpbm 11.5.2 executable.
  • The dimming factor is between 0.0 and 1.0, inclusive.
  • The source PPM remains untouched and the result has a separate filename.
  • file reports the expected PPM format and dimensions.
  • You checked the image visually or with a trusted downstream converter.
  • Temporary test files and backups were removed only after the replacement was verified.