Build a Windows ICO from PAM Images with pamtowinicon
pamtowinicon takes one or more Netpbm PAM images and bundles them into a single Windows icon file, in the same order you fed them in. Allow about fifteen minutes if the PAM input already exists. The examples use Netpbm 11.5.2, installed here as Debian package version 2:11.05.02-1.1build1.
The route
Jump straight to the step you need, or tick off Done means at the end.
- You need: a shell, the
netpbmpackage, and an input PAM file. - Output goes to stdout. The converter writes binary ICO data to standard output, so redirect it to a new file, then inspect the file with an image-aware command.
- No elevated privileges unless your input or destination directory is deliberately restricted.
1. Check the installed command
Confirm which executable will run and record the local implementation version:
$ command -v pamtowinicon
/usr/bin/pamtowinicon
$ pamtowinicon --version
pamtowinicon: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pamtowinicon: Built from source dated 2024-03-31 09:09:47
This output includes build details and is written as diagnostic text; do not redirect it into the icon. The manual says options may use one or two hyphens, and that a name can be separated from its value with whitespace or an equals sign. Full option names read more clearly in scripts.
2. Check the PAM images and channel meaning
pamtowinicon reads a multi-image PAM file: several complete images back to back, no padding between them, each with its own header and raster. Use pamfile when it is installed to see the images before conversion:
$ pamfile /path/to/input.pam
PAM file: 64 by 64 by 4 maxval 255
PAM file: 128 by 128 by 4 maxval 255
The exact wording can vary by Netpbm release, but the useful facts are the dimensions and depth. The converter reads depth like this:
- Depth 1 is an opaque greyscale image.
- Depth 2 is greyscale with a transparency channel.
- Depth 3 is an opaque colour image.
- Depth 4 is colour with a transparency channel.
- Depth 5 is colour with a transparency channel and a separate Windows AND mask.
Here is the catch: the PAM tuple type does not control this, depth does. A file claiming RGB_ALPHA with depth 3 needs the producing step or the PAM header fixed before you rely on its transparency. Keep a copy of the original while you investigate malformed input.
3. Convert a multi-image PAM file to ICO
Choose a new destination and redirect standard output there:
$ pamtowinicon /path/to/input.pam > /path/to/icon.ico
Every input image becomes one image in the ICO, same order. A successful run normally prints nothing, since the icon itself is binary standard output, so check the exit status straight away if you are scripting it:
$ printf '%s\n' "$?"
0
Zero means conversion completed. It does not prove the source dimensions or visual content are what you intended, so carry on to file inspection.
4. Verify the icon and its image count
Use file for a quick structural check. For the two-image, 2 by 2 RGBA test input used on this machine, the installed command produced:
$ file /tmp/pamtowinicon.ico
/tmp/pamtowinicon.ico: MS Windows icon resource - 2 icons, 2x2, 32 bits/pixel, 2x2, 32 bits/pixel
Your dimensions and bit depth will differ. Look for a Windows icon resource, the expected number of icons, and the expected dimensions. A further check with an image viewer or Windows application is worth doing when transparency matters. Do not treat a text editor or head as an image validator: an ICO holds binary headers, pixel data and possibly embedded PNG data.
Add -verbose for more detail. It keeps the icon on standard output but reports each encoding decision on standard error:
$ pamtowinicon -verbose /path/to/input.pam > /path/to/icon.ico
pamtowinicon: Image 0: encoding as BMP
pamtowinicon: Image 0: 64 x 64 x 4, 256 colors, alpha channel
pamtowinicon: Image 1: encoding as BMP
The wording and colour count depend on the input. The useful bit is whether each image was encoded as BMP or PNG, and whether an alpha channel was found.
5. Choose PNG encoding for larger images
By default, the threshold is 128: images at or above that resolution get encoded as PNG by running pnmtopng, smaller ones use the traditional BMP form. Set a different threshold when your icon set has a deliberate size or compatibility policy:
$ pamtowinicon -pngthreshold=64 /path/to/input.pam > /path/to/icon.ico
$ pamtowinicon -pngthreshold 64 /path/to/input.pam > /path/to/icon-64.ico
Resolution here means the image dimensions as the program understands them, not the file's byte size. Test the resulting ICO on the consumers that matter to you. One catch: when PNG encoding is selected for a five-channel PAM, the separate AND mask is discarded, since PNG already carries transparency. Skip this mode if that mask has behaviour your target software needs.
6. Handle transparency and the AND mask
For a two- or four-channel input with no explicit AND mask, the program derives one from transparency: a transparency sample below maxval counts as opaque in the AND mask, a sample at the maximum is transparent, and an input with no transparency channel at all is treated as fully opaque.
Windows uses the AND mask for more than simple alpha, including things like the icon's look while it is being dragged. If the background appears inverted or otherwise wrong in older BMP-based handling, try:
$ pamtowinicon -truetransparent /path/to/input.pam > /path/to/icon-transparent.ico
This makes pixels outside the opaque area black. It changes the generated icon, so compare both files in the target environment; the option does not alter the PAM input itself.
7. Avoid destroying an existing icon
Shell redirection with > truncates its destination before pamtowinicon starts. Do not point it at the only copy of a working icon. Write a temporary sibling and replace the old file only after verification:
$ pamtowinicon /path/to/input.pam > /path/to/icon.ico.new
$ file /path/to/icon.ico.new
$ mv -- /path/to/icon.ico.new /path/to/icon.ico
Warning
The final mv is the state-changing step. If conversion or verification fails, leave the original alone and remove the incomplete .new file once you have confirmed its path. If the replacement turns out wrong, restore a backup or rename the old file back before deleting anything. Do not use sudo merely because the output is an icon; reach for elevated access only when filesystem permissions actually require it.
Done means
- Checked the installed Netpbm version and input PAM dimensions.
- Wrote a new ICO from standard output and got status 0 back.
- Confirmed the ICO reports the expected image count, dimensions and encoding shape.
- Matched PNG threshold and transparency choices to the software that will read the icon.
- Kept the original input and any known-good icon recoverable until the replacement was verified.