Converta imagem em paleta específica usando PIL sem pontilhamento
Estou tentando converter uma imagem RGB em formato PNG para usar uma paleta indexada específica usando a biblioteca Pillow (Python Image Library, PIL). Mas quero converter usando o método "arredondar para a cor mais próxima", não o pontilhamento, porque a imagem é pixel art e o pontilhamento distorceria os contornos das áreas e acrescentaria ruído às áreas que deveriam ser planas.
eu tenteiImage.Image.paste()
, e usou as quatro cores especificadas, mas produziu uma imagem pontilhada:
from PIL import Image
oldimage = Image.open("oldimage.png")
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
newimage = Image.new('P', oldimage.size)
newimage.putpalette(palettedata * 64)
newimage.paste(oldimage, (0, 0) + oldimage.size)
newimage.show()
eu tenteiImage.Image.quantize()
como mencionado emresposta de pictu para uma pergunta semelhante, mas também produziu pontilhamento:
from PIL import Image
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
palimage = Image.new('P', (16, 16))
palimage.putpalette(palettedata * 64)
oldimage = Image.open("School_scrollable1.png")
newimage = oldimage.quantize(palette=palimage)
newimage.show()
eu tenteiImage.Image.convert()
e converteu a imagem sem pontilhamento, mas incluiu cores diferentes das especificadas, provavelmente porque usava uma paleta da Web ou uma paleta adaptável
from PIL import Image
oldimage = Image.open("oldimage.png")
palettedata = [0, 0, 0, 102, 102, 102, 176, 176, 176, 255, 255, 255]
expanded_palettedata = palettedata * 64
newimage = oldimage.convert('P', dither=Image.NONE, palette=palettedata)
newimage.show()
Como converter automaticamente uma imagem em uma paleta específica sem pontilhar? Gostaria de evitar uma solução que processe cada pixel individual em Python, conforme sugerido emResposta de John La Rooy e comentários a ele, porque minha solução anterior envolvendo um loop interno escrito em Python provou ser notavelmente lenta para imagens grandes.