linux - Convert image to uncompressed PNG from the command-line

09
2013-08
  • Mechanical snail

    I have a compressed PNG image compressed.png. I can convert it to an uncompressed PNG decompressed.png using GIMP (saving as PNG and setting compression level to 0). How can this be done on the command line (Linux)?

    I recall doing this in the past using Imagemagick's convert, but I forgot how. I tried some things that I thought should work based on the documentation:

    • convert compressed.png -compress None decompressed.png
    • convert compressed.png +compress decompressed.png
    • convert compressed.png -quality 0 decompressed.png
    • convert compressed.png -quality 00 decompressed.png

    just wrote an ordinary compressed PNG.

    Aside: why would you want an uncompressed PNG?

    Some cases:

    • You want to support efficient (binary) diffs of the image data, while still using other features of the PNG format (as opposed to storing raw image data or BMP).
    • You want to compress several PNGs together in a tarball or 7z archive, but want to keep using PNG features. If the images are sufficiently similar this can give a better compression ratio than compressing individually.
    • Useful as a baseline size for testing PNG optimizers.
  • Answers
  • MV.

    ImageMagick will always compress PNG files. The worst compression you can get is using:

    convert -verbose -quality 01 input.png output.png
    

    but it depends on the image content (the 0 will use Huffman compression which sometimes compress better than zlib).

    You can try other tools like pngcrush (http://pmt.sourceforge.net/pngcrush/) to disable the compression:

    pngcrush -force -m 1 -l 0 input.png output.png
    

    which create a file the same size GIMP create when using Compression Level 0 (few bytes more or less).

    Some example sizes (for a photographic PNG, 1600x1200):

    • original: 1,693,848 bytes.
    • after IM: 2,435,983 bytes.
    • after GIMP: 5,770,587 bytes.
    • after pngcrush: 5,802,254 bytes.
  • Selenium

    To quote the ImageMagick doc: Not all combinations of compression level, strategy, and PNG filter type can be obtained using the -quality option. For more precise control, you can use the -define option.

    For example, this command should create an uncompressed (RGB) PNG file:

    convert INFILE \
    -define png:compression-level=0 \
    -define png:compression-filter=0 \
    -define png:color-type=2 \
    OUTFILE.png
    

    You might get a warning, which is a harmless bug. It will still produce a correct png. http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20257

    Sample image:

    112233 112233 112233 112233
    445566 445566 445566 445566
    778899 778899 778899 778899
    aabbcc aabbcc aabbcc aabbcc
    

    IDAT chunk of the PNG file created with IM:

    49444154081d013400cbff00
    11223311223311223311223300
    44556644556644556644556600
    77889977889977889977889900
    aabbccaabbccaabbccaabbcc
    7d6f14b9...
    

    However, for certain cases (e.g. group compression) it could be worthwhile testing a format with less overhead, for example TARGA (.tga).

  • Sam Watkins

    I like the netpbm suite of tools, it is designed in the UNIX "software tools" tradition: "write programs that do one thing and do it well".

    You can do what you asked like this:

    < in.png pngtopnm > image.pnm
    < in.png pngtopnm -alpha > alpha.pnm
    <image.pnm pnmtopng -alpha alpha.pnm -compression 0 > out.png
    rm image.pnm alpha.pnm
    

    You might lose certain metadata from the original png file.

    It seems a bit complicated, due to the way we handle the alpha channel.

    Netpbm is a toolkit for manipulation of graphic images, including conversion of images between a variety of different formats. There are over 220 separate tools in the package including converters for more than 80 graphics formats.


  • Related Question

    What is the fastest way to convert 50 PNGs to JPGs in Ubuntu?
  • Matthew

    Possible Duplicate:
    Batch converting PNG to JPG in linux

    I have about 50 PNGs that are about 10Mb each (fully compressed). I want to convert them to JPGs with maximum quality, so that they fall just under Facebook's 5Mb limit. I can manually convert each one in the GIMP, but this seems like a bit of a pain. Is there an easy way to convert them all at once?

    Edit: mogrify -format jpg *.png seems to be pretty much what I'm looking for. However, it compresses to around 1.5mb. When I select maximum quality in GIMP, it saves them at around 4mb. Is there a way to control the compression rate with mogrify?


  • Related Answers
  • Mokubai

    Try mogrify -format jpg -quality 90 *.png and the pictures should come out a lot smaller.

    The "quality" number is a 0 - 100 integer value where 0 is worst and 100 is best, chances are mogrify defaults to 100 hence the large file sizes. 90 is a good point to start at as it compresses quite well and you'll be able to see almost no difference to the original image. Below around 75 you'll probably start to see artifacts and poor quality, depending on your eyesight and personal aesthetic.