I have a device that supports 4-color graphics (much like CGA in the old days).
I wanted to use PIL to read the image and convert it using my 4-color palette (of red, green, yellow, black), but I can't figure out if it's even possible at all. I found some mailing list archive posts that seem to suggest other people have tried to do so and failed.
A simple python example would be much appreciated!
Bonus points if you add something that then converts the image to a byte string where each byte represents 4 pixels of data (with each two bits representing a color from 0 to 3)
import sys
import PIL
from PIL import Image
def quantizetopalette(silf, palette, dither=False):
"""Convert an RGB or L mode image to use a given P image's palette."""
silf.load()
# use palette from reference image
palette.load()
if palette.mode != "P":
raise ValueError("bad mode for palette image")
if silf.mode != "RGB" and silf.mode != "L":
raise ValueError(
"only RGB or L mode images can be quantized to a palette"
)
im = silf.im.convert("P", 1 if dither else 0, palette.im)
# the 0 above means turn OFF dithering
return silf._makeself(im)
if __name__ == "__main__":
import sys, os
for imgfn in sys.argv[1:]:
palettedata = [ 0, 0, 0, 0, 255, 0, 255, 0, 0, 255, 255, 0,]
palimage = Image.new('P', (16, 16))
palimage.putpalette(palettedata + [0, ] * 252 * 3)
oldimage = Image.open(sys.argv[1])
newimage = quantizetopalette(oldimage, palimage, dither=False)
dirname, filename= os.path.split(imgfn)
name, ext= os.path.splitext(filename)
newpathname= os.path.join(dirname, "cga-%s.png" % name)
newimage.save(newpathname)
For those that wanted NO dithering to get solid colors. i modded: Convert image to specific palette using PIL without dithering with the two solutions in this thread. Even though this thread is old, some of us want that information. Kudios
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With