Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert any image to a 4-color paletted image using the Python Imaging Library?

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)

like image 851
Thomas Vander Stichele Avatar asked Oct 25 '08 17:10

Thomas Vander Stichele


1 Answers

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

like image 169
Lady_F Avatar answered Oct 02 '22 11:10

Lady_F