Search code examples
pythonimagepalette

PIL: Convert RGB image to a specific 8-bit palette?


Using the Python Imaging Library, I can call

img.convert("P", palette=Image.ADAPTIVE)

or

img.convert("P", palette=Image.WEB)

but is there a way to convert to an arbitrary palette?

p = []
for i in range(0, 256):
    p.append(i, 0, 0)
img.convert("P", palette=p)

where it'll map each pixel to the closest colour found in the image? Or is this supported for Image.WEB and nothing else?


Solution

  • While looking through the source code of convert() I saw that it references im.quantize. quantize can take a palette argument. If you provide an Image that has a palette, this function will take that palette and apply it to the image.

    Example:

        src = Image.open("sourcefilewithpalette.bmp")
        new = Image.open("unconvertednew24bit.bmp")
        converted = new.quantize(palette=src)
        converted.save("converted.bmp")
    

    The other provided answer didn't work for me (it did some really bad double palette conversion or something,) but this solution did.