PIL:将RGB图像转换为特定8位调色板?
我可以使用Python图像库,调用
img.convert("P", palette=Image.ADAPTIVE)
或者
img.convert("P", palette=Image.WEB)
但是有没有办法转换成任意调色板呢?
p = []
for i in range(0, 256):
p.append(i, 0, 0)
img.convert("P", palette=p)
也就是说,它能把每个像素映射到图像中最接近的颜色吗?还是说这只对Image.WEB
有效,其他的就不行?
2 个回答
3
ImagePalette
模块的文档中第一个例子展示了如何将调色板附加到一张图片上,但这张图片必须已经是“P”或“L”模式。不过,我们可以稍微调整这个例子,把一张完整的RGB图片转换成你想要的调色板:
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()
9
在查看convert()
的源代码时,我发现它提到了im.quantize
。quantize
这个函数可以接受一个调色板参数。如果你提供一个有调色板的图像,这个函数就会把那个调色板应用到图像上。
举个例子:
src = Image.open("sourcefilewithpalette.bmp")
new = Image.open("unconvertednew24bit.bmp")
converted = new.quantize(palette=src)
converted.save("converted.bmp")
之前提供的答案对我没用(它做了一些很糟糕的双重调色板转换之类的),但这个解决方案有效。