PIL: Convert RGB image to a specific 8-bit palette?
Solution 1
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.
Solution 2
The ImagePalette
module docs's first example shows how to attach a palette to an image, but that image must already be of mode "P"
or "L"
. One can, however, adapt the example to convert a full RGB image to a palette of your choice:
from __future__ import division
import Image
palette = []
levels = 8
stepsize = 256 // levels
for i in range(256):
v = i // stepsize * stepsize
palette.extend((v, v, v))
assert len(palette) == 768
original_path = 'original.jpg'
original = Image.open(original_path)
converted = Image.new('P', original.size)
converted.putpalette(palette)
converted.paste(original, (0, 0))
converted.show()
Related videos on Youtube
mcccclean
Updated on April 25, 2022Comments
-
mcccclean about 2 years
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? -
Edward Falk about 9 yearsHave you tested this?
-
Mike Boers about 9 yearsI'm pretty sure I did at the time (~5 years ago). Did it not work for you?
-
Edward Falk about 9 yearsI didn't try. I wound up using im.quantize()