Konvertieren Sie das Bild mit PIL in eine bestimmte Palette, ohne zu ditheren

Ich versuche, ein RGB-Bild im PNG-Format mithilfe der Pillow-Bibliothek (Python Image Library, PIL) in eine bestimmte indizierte Palette umzuwandeln. Aber ich möchte mit der Methode "Runden auf nächstgelegene Farbe" konvertieren, nicht mit Dithering, da das Bild Pixelkunst ist und Dithering die Konturen von Bereichen verzerren und Rauschen zu Bereichen hinzufügen würde, die flach sein sollen.

Ich habe es versuchtImage.Image.paste(), und es wurden die vier angegebenen Farben verwendet, es wurde jedoch ein gedithertes Bild erzeugt:

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()    

Ich habe es versuchtImage.Image.quantize() wie in @ erwäh Pictus Antwort auf eine ähnliche Frage, aber es hat auch Dithering erzeugt:

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()

Ich habe es versuchtImage.Image.convert(), und das Bild wurde ohne Dithering konvertiert, es enthielt jedoch andere als die angegebenen Farben, vermutlich weil entweder eine Web-Palette oder eine adaptive Palette verwendet wurde.

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()

Wie konvertiere ich ein Bild automatisch ohne Dithering in eine bestimmte Palette? Ich möchte eine Lösung vermeiden, die jedes einzelne Pixel in Python verarbeitet, wie in @ vorgeschlage John La Rooys Antwort und Kommentare dazu, weil sich meine vorherige Lösung mit einer in Python geschriebenen inneren Schleife für große Bilder als bemerkenswert langsam erwiesen hat.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage