[Image-SIG] Best Method to Dither a Grayscale image

Christian M. Jensen christianj at implicitnetworks.com
Mon Jul 18 23:13:15 CEST 2005


I would like to convert a 256 level image down to 32 or 64 levels using
the best dithering possible for visual niceness.

Am I better off using im.convert() or im.quantize()?

I have tried upsampling to an RGB image then using a prebuilt 32 gray
palette to downsample to 32 colors but it is not dithering using the
given palette. It appears to be using an adaptive palette or something.

Anyone have any input?

import Image
import ImagePalette

from math import *

def createGray(x):
    values = int(pow(2,x))
    out = []
    for i in range(256):
        k = int(round((i/255.0)*values)/float(values)*255)
        out.append(k)
        out.append(k)
        out.append(k)
    return out

def doDither(im, x):
    data = createGray(x)
    p = ImagePalette.ImagePalette("RGB", data)
    pimage = Image.new("P", (10, 10))
    pimage.putpalette(data)
    im = im.convert(mode="RGB")
    im = im.convert(mode="P", palette=pimage)
    im = im.convert(mode="L")
    return im
    
im = Image.open("input.png")
bands = im.split()

RO = doDither(bands[0], 5)
GO = doDither(bands[1], 6)
BO = doDither(bands[2], 5)

outbands = [RO, GO, BO, bands[3]]
outimage = Image.merge("RGBA", outbands)
outimage.save("output.png")



More information about the Image-SIG mailing list