views:

101

answers:

2

Hello,
I want to convert the input 24 bit PNG image to 8 bit, I have tried using Imagemagick and Python PIL, neither works.

for instance:

at Imagemagick I try convert console command as such:

convert -depth 8 png24image.png png8image.png

And here is the way I tried with python:

import Image
def convert_8bit(src, dest):
    """
    convert_8bit: String, String -> void.
    Converts the input image file into 8bit depth.
    """
    im = Image.open(src)
    if not im.mode == "P":
        im2 = im.convert("P", rgb2xyz)
        im2.save(dest)

Imagemagick doesn't even touch the image while the python function reduces to 8bit but keeps the number of unique numbers 164instead of 256. Photoshop used to convert the image to 8bit with 256unique numbers when converted to png8 from a 24 bit png image.

Thanks

EDIT:

Output of 24->8 png conversion via Photoshop (which I need) alt text

Converted via my Python function

alt text

A: 

I do it like this (using Imagick in PHP):

$colors = min(255, $im->getImageColors());
$im->quantizeImage($colors, Imagick::COLORSPACE_RGB, 0, false, false );
$im->setImageDepth(8 /* bits */);
Sjoerd
I use python and have very limited php knowledge thus the convert command version of this would be lovely :)
Hellnar
+1  A: 

It looks like the quantization method on the convert method isn't doing the right thing. Try this:

im2 = im.convert('RGB').convert('P', palette=Image.ADAPTIVE)

The extra conversion to RGB may be redundant. I got this hint from http://nadiana.com/pil-tips-converting-png-gif

Mark Ransom
I have the impression that without the `palette=Image.ADAPTIVE` parameter, PIL uses only “web-safe” colours.
ΤΖΩΤΖΙΟΥ
@ΤΖΩΤΖΙΟΥ, yes I think I saw that in the documentation somewhere. There's really no reason to use web-safe colors anymore - it was for a time when graphics adapters were much less capable. It results in a picture that looks bad and is less compressible too!
Mark Ransom