Converting PNG32 file to PNG8 without losing alpha channel

5

3

I'm using Linux and have no access to any of Adobe's 'fancy' programs.

I'm trying to convert an existing PNG32 image with alpha channel to PNG8. I have tried the following methods:

  • convert original.png PNG8:new.png - Horribly distorts the image and preserving only binary alpha (Not Indexed alpha)
  • GIMP - Fails as well, but produces better quality (good color quantizer) than ImageMagick.
  • pngcrush -rem alla -reduce -brute original.png new.png - Made the image smaller but didn't take quantization into account (Image has less than 256 colors), so output was still PNG32.

What else can I try?

LiraNuna

Posted 2009-10-06T21:53:17.320

Reputation: 1 664

Answers

1

This PHP script does the trick with libgd:

<?PHP

if(!isset($argv[1]) || !is_readable($argv[1])) {
    echo "Creates an 8-bit PNG from a 32-bit PNG\n\n";
    echo "Usage:\n";
    echo "\t" . $argv[0] . " input.png > output.png\n";
    echo "\t" . $argv[0] . " input.png output.png\n";
    die();
}

$inFile = $argv[1];
$outFile = $argv[2] or STDOUT;

$inImage = imagecreatefrompng($inFile);
$outImage = imagecreate(imagesx($inImage), imagesy($inImage));

imagecopy($outImage, $inImage, 0, 0, 0, 0, imagesx($inImage), imagesy($inImage));

imagepng($outImage, $outFile);

Dump that into a file and run it as:

php convert.php input.png output.png

strager

Posted 2009-10-06T21:53:17.320

Reputation: 376

2

I know I'm a bit late to the party, but this recently bit me on a web project I'm working on.

I used pngnq for batch conversion and my PNG8 have never looked better. In fact, with the highest sampling rate (-s 1) the results are nearly indistinguishable from a full PNG32.

Josh

Posted 2009-10-06T21:53:17.320

Reputation: 21

What a useful link, thanks! I've been looking for such a tool for some time. Tested pngnq and it produces an excellent result, small file and smooth alpha. – jjrv – 2011-11-26T21:21:53.087

1

Your distro may include pngquant. If you can't find it with yum / apt-get, go to the web site. I think this is your best bet.

If you're having issues with pngquant, you can try pngout, but it's a long shot. I've heard it does a good job retaining the alpha channel, but can be slow. Possibly the slowness people experience is because the default 'strategy' is 'Extreme' which the author admits is slow.

It's a windows program, but there are linux ports (supposedly), but the link on the pngout authors page is out of date. The linux port maintainer, JonoF, maintains a page here now.

I have to admit to not ever having used it. Good luck!

DaveParillo

Posted 2009-10-06T21:53:17.320

Reputation: 13 402

pngquant doesn't preserve alpha channel. It produces the same output as GIMP. – LiraNuna – 2009-10-07T20:23:02.357

pngout will not cooperate - Unable to compress further: copying original file – LiraNuna – 2009-10-07T20:36:08.463

wow. can you make this image available somewhere? I'd like to take a crack at it. – DaveParillo – 2009-10-08T00:47:44.083

Just take any PNG32 image, I'm actually using one of the icons from Silk iconset - http://www.famfamfam.com/lab/icons/silk/.

– LiraNuna – 2009-10-09T04:15:58.347

All the icons in famfamfam_silk_icons_v013.zip appear to be 8-bit. I'm having trouble finding a 32 bit image on the web. Don't want to make one myself using the tools that are causing your grief as that's not likely a valid test. – DaveParillo – 2009-10-09T04:38:25.963

found a 32bit image with I think every possible transparency levle set: http://www.virtualmechanics.com/support/tutorials-spinnerpro/image/obj4120geo2655shd297pg5p6.png. Now I see your problem ;-)

– DaveParillo – 2009-10-09T21:45:57.213

0

Use pngquant, but make sure you have version later than 1.6. The latest version has very good quantizer that will beat PHP's libGD by far, in every case.

Debian wheezy still contains a 13-year-old version that has low quality output. There's a good pngquant package for Debian experimental, and most other Linux distros.

If your distro has only outdated pngquant, then use pngnq instead.

Kornel

Posted 2009-10-06T21:53:17.320

Reputation: 1 225