2

I have a PNG image processing workflow that relies on the images to be in the 24bit Truecolor format also known as RGB images. PNG permits either RGB or Indexed color representation.

The pnmtopng program from NetPBM automatically decides which type of image to write depending on the number of distinct colors in the image. I recall reading somewhere that if this number is 256 or fewer, it automatically writes an Indexed image.

Is there a way to preserve the type of the image?

For instance if I am using NetPBM to flip an image as follows

pngtopnm true-color-image.png | pamflip -tb | pnmtopng > new-image.png

Is there a way to ensure that new-image will also be a Truecolor image?

At the moment I can check that the image is of a wrong type, because its size is about 50% less than that of the original image.

37155 true-color-image.png
27463 new-image.png

I expect the new image to be about the same size as the original.

Also identify from ImageMagick gives the following for these two images:

true-color-image.png PNG 300x280 300x280+0+0 8-bit sRGB 37155B
new-image.png PNG 300x280 300x280+0+0 8-bit sRGB 61c 27463B

2 Answers 2

2

I have found a solution in PNG: The Definitive Guide (Ch. 5) by Greg Roelofs.

It reads:

Observant readers will recall that GIF images are always palette-based, yet I didn't say anything about palettes in describing the NetPBM format. In fact, NetPBM has no concept of palettes; giftopnm usually converts GIF images into PPM format (the RGB flavor). Fortunately, pnmtopng is smart enough to count the colors in an image and automatically write a palette-based PNG image if there are 256 or fewer colors. It will likewise detect if a color image is actually composed only of gray values; in that case, it will write either a grayscale PNG or a palette-based one, depending on which can be written with the fewest bits. This automatic checking comes at a cost, however: because it requires inspection of every pixel, it can be quite slow for large images. pnmtopng therefore includes a -force option to skip the checking.

So, while the main intention of introducing -force option was to speed up conversion. In my case it helps ensure compatibility.

pngtopnm true-color-image.png | pamflip -tb | pnmtopng > flipped-indexed.png
pngtopnm true-color-image.png | pamflip -tb | pnmtopng -force > flipped-truecolor.png

Running identify confirms that the option works as expected.

flipped-indexed.png PNG 300x280 300x280+0+0 8-bit sRGB 61c 27463B 0.000u 0:00.000
flipped-truecolor.png PNG 300x280 300x280+0+0 8-bit sRGB 37038B 0.000u 0:00.000

For the sake of completeness here is a full example.

# 1. Generate a green/blue two color image
ppmrough -left 30 -right 30 -top 30 -bottom 30 -width 300 -height 280 \
         -var 5 -bg green -fg blue > twocolor.ppm
# 2. Convert to PNG
pnmtopng twocolor.ppm > twocolor-indexed.png
# 3. Convert to PNG forcing Truecolor output
pnmtopng -force twocolor.ppm > twocolor-truecolor.png
# 4. Checking the results
identify twocolor-indexed.png twocolor-truecolor.png

This would produce two PNG images. One with a 2-color indexed palette, the other a Truecolor PNG.

twocolor-indexed.png PNG 300x280 300x280+0+0 8-bit sRGB 2c 1018B 0.000u 0:00.000
twocolor-truecolor.png PNG 300x280 300x280+0+0 8-bit sRGB 2421B 0.000u 0:00.000
1

This smells like an XY problem to me.

png is a compressed image format and is designed to store the image in the smallest possible way without reducing or altering information content. If the image has 256 colors or fewer, it can store it as indexed without losing any RGB data.

Your application should not care if it is indexed or true color format if it is using a suitable library to read the image. It should get the same raw data for the pixels in the image either way. If you hand coded a png decoder that can't handle indexed images, it may be a good idea to switch to a library instead.

If you really want a raw RGB image that is not indexed, you should convert it to ppm instead of a png.

1
  • The point re X vs. Y problem is definitely valid, and your suggestion of using PPMs directly without converting to PNG does solve my problem. The next stage of my pipeline is using rasterio, that works on top of GDAL, that support PPM rasters directly. What I find contentious is that PNG is not a complete replacement for PPM. Commented Nov 21, 2023 at 13:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .