[PYTHON IMAGE-SIG] PIL and palettes and drawing.

Anthony Baxter Anthony Baxter <arb@connect.com.au>
Tue, 17 Dec 1996 21:11:59 +1100


This is a multipart MIME message.

--===_0_Tue_Dec_17_21:06:55_EST_1996
Content-Type: text/plain; charset=us-ascii


>>> Fredrik Lundh wrote
> The ImagePalette module doesn't work as it should, so it really takes
> some magic to do what you need:

Ok, I've played with this some more (motivated in this case by a desire to 
avoid writing a whitepaper which really is due all-to-soon :) and I've 
come up with a new ImagePalette class, which Does What I Want.

It's attached at the end. Please let me know what you think.

sample usage:

    im=Image.new("P",(400,400))
    pal=ImagePalette.ImagePalette()
    pal[0] = (0,0,0)
    pal[1] = (255,0,0)
    pal[2] = "#FF00E0"  # alternative use
    pal[3] = (100,255,100)
    pal[4] = (0,0,255)
    print pal[0],pal[1],pal[2],pal[3],pal[4]

    # this is the bit I'm not _entirely_ happy with, syntax-wise.
    pal.attach(im) # or just pal(im)

    draw=ImageDraw.ImageDraw(im)
    draw.setink(0)
    draw.rectangle((0,0,400,400)
    draw.setink(1)
    draw.rectangle((10,10,40,40)

Anthony.

(btw, any ideas which is a good format to be writing type P images to? 
at the moment I'm converting them to RGB, then writing them as ppm. I
can't have the lossiness of jpg, and the tiff writer doesnt write the
colourmap)

--===_0_Tue_Dec_17_21:06:55_EST_1996
Content-Type: text/plain; charset=us-ascii
Content-Description: ImagePalette.py
Content-Transfer-Encoding: quoted-printable

#
# The Python Imaging Library.
# $Id: ImagePalette.py,v 1.4 1996/11/10 17:52:14 fredrik Exp $
#
# image palette object
#
# History:
#       96-03-11 fl     Rewritten.
#       1996-12-16 arb  Rewritten again, to be useful. :)
#
# Copyright (c) Fredrik Lundh 1996.  All rights reserved.
#

import array
import Image

class ImagePalette:

    def __init__(self,mode=3D"RGB",palette=3DNone):
	self.mode=3Dmode
	if not palette:
	    self.palette=3Dlist(range(256)*len(self.mode))
	else:
	    if type(palette) =3D=3D type(""):
		self.palette=3Dmap(ord,palette)
	    else:
		self.palette=3Dpalette
	if len(self.mode)*256 !=3D len(self.palette):
            raise ValueError, "wrong palette size"
 =

    def tostring(self):
        return array.array("b", self.palette).tostring()

    # handle either a tuple of (r,g,b) or "#RRGGBB" where RR,GG,BB are he=
x
    # numbers in range 00-FF.
    def set(self,num,col):
	print num,col,type(num),type(col)
	if type(col) is type(()):
	    r,g,b=3Dcol
	    self.palette[0+(num*3)] =3D r
	    self.palette[1+(num*3)] =3D g
	    self.palette[2+(num*3)] =3D b
	    return None
	if type(col) is type(''):
	    if col[0] =3D=3D '#' and len(col) =3D=3D 7:
		import string
		self.palette[0+(num*3)] =3D string.atoi(col[1:3],16)
		self.palette[1+(num*3)] =3D string.atoi(col[3:5],16)
		self.palette[2+(num*3)] =3D string.atoi(col[5:7],16)
		return None
	    # handle UNIX rgb.txt?
	raise ValueError,"not a valid colour setting"

    def attach(self,image):
	import string
	if hasattr(image,'im') and hasattr(image,'mode') and image.mode =3D=3D '=
P':
	    p=3Dmap(chr,self.palette)
	    image.im.putpalette(self.mode,string.join(p,''))

    def __setitem__(self,name,val):
	if type(name) =3D=3D type(1):
	    self.set(name,val)

    def __getitem__(self,num):
	return self.palette[num*3],self.palette[(num*3)+1],self.palette[(num*3)+=
2]

    def __call__(self,image):
	self.attach(image)

    def save(self, fp):
        if type(fp) =3D=3D type(""):
            fp =3D open(fp, "w")
        fp.write("# Palette\n")
        fp.write("# Mode: %s\n" % self.mode)
        for i in range(256):
            fp.write("%d" % i)
            for j in range(i, len(self.palette), 256):
                fp.write(" %d" % self.palette[j])
            fp.write("\n")
        fp.close()

# --------------------------------------------------------------------
# Factories
 =

def new(mode, data):
    Image.core.new_palette(mode, data)
 =

def negative(mode =3D "RGB"):
    palette =3D range(256)
    palette.reverse()
    return ImagePalette(mode, palette * len(mode))
 =

def random(mode =3D "RGB"):
    from whrandom import randint
    palette =3D map(lambda a,randint=3Drandint: randint(0, 255), [0]*256*=
len(mode))
    return ImagePalette(mode, palette)
 =

def wedge(mode =3D "RGB"):
    return ImagePalette(mode, range(256) * len(mode))
 =

# add some psuedocolour palettes as well

	=


def test():
    im=3DImage.open("ltest.gif")
    pal=3DImagePalette(im.palette[0],im.palette[1])
    print pal[0],pal[1],pal[2],pal[3],pal[4]
    print pal[255]


if __name__ =3D=3D "__main__":
    test()

--===_0_Tue_Dec_17_21:06:55_EST_1996--



=================
IMAGE-SIG - SIG on Image Processing with Python

send messages to: image-sig@python.org
administrivia to: image-sig-request@python.org
=================