To paletted image

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bearophileHUGS@lycos.com

    #1

    To paletted image

    Hello, this time I have a question about PIL usage, maybe if Lundh has
    some time he can answer me.
    I am experimenting different color quantization algorithms, so having
    computed the palette with a clustering function, I use the code below
    to quantize the original image to produce an image without dithering
    (so I can see better the quantization results).

    I have seen that the *standard* distance function I use isn't standard
    enough, because given the fixed palette computed by me, most graphics
    programs give me a different (better) quantized image. I don't know
    what's wrong/different in this quantize function, maybe you can tell
    me.


    I'd also like to know if there is a simpler code for PIL to do the same
    thing (given my palette and a truecolor image), but this is less
    important. I know the dither=Image.NO NE for the im.convert() method,
    but I don't know a good way to use it in this problem. (Note that the
    quantize function below uses a perceptual-based color distance, but to
    do the quantization with PIL I can settle with its standard color
    distance function.)

    Thank you,
    bearophile


    # Input:
    # im = input truecolor image
    # palette = a palette computed by me, of about 32 colors
    # im_out = output image with no dithering

    def quantize(data, palette_short):
    out_data = []
    for rgb in data:
    dist_min = 1e100
    closest_col = None
    for col_pos, pal_col in enumerate(palet te_short):
    # Standard distance
    #dr = rgb[0] - pal_col[0]
    #dg = rgb[1] - pal_col[1]
    #db = rgb[2] - pal_col[2]
    #d = dr*dr + dg*dg + db*db
    d = perceptualColor Distance(rgb, pal_col)
    if d < dist_min:
    dist_min = d
    closest_col = col_pos
    out_data.append (closest_col)
    return out_data

    #..........
    import psyco; psyco.bind(quan tize)

    # Copy of palette, to speed up quantization
    palette_short = list(palette)

    # Add duplicated colors (the last one) to produce a palette of 256
    colors
    palette.extend( palette[-1] for i in xrange(256 - len(palette)) )

    # Create empty paletted output image
    im_out = Image.new("P", im.size, 0)

    # Flatten the list of colors, for PIL
    #flattened_pale tte = flatten(palette )
    flattened_palet te = [component for color in palette for component in
    color]

    # Put the computed palette in the output image
    im_out.putpalet te(flattened_pa lette)

    # quantize the input image with the computed palette
    out_data = quantize(data, palette_short)

    # Put the computed data inside the output image
    im_out.putdata( out_data)

    # Save computed output image
    im_out.save(out _filename)

Working...