Tkinter PhotoImage or PIL transparent subimages

Mark 'Kamikaze' Hughes kamikaze at kuoi.asui.uidaho.edu
Sun Jul 20 08:26:42 CEST 2003


  In the new Python game I'm developing, I need to crop out individual
tiles from larger tilesets, and maintain transparency.  Unfortunately,
I've run into major deficiencies in both Tkinter and PIL (PyGame,
wxPython, PyQt, etc. are not really suitable for this program, for a
number of reasons, and I have zero interest in discussing why right
now).

  Since the Tkinter.PhotoImage.copy() method doesn't allow a region
parameter, I have to save the tile to a disk file (write does have a
region parameter) and read it back in; this does work correctly, but
it's not very fast.  Tk's copy() method *does* support a region
parameter, but Tkinter inexplicably does not pass it through.  It'd
probably take someone who can program in C and knows the Tkinter library
30 minutes to fix this, check it in for Python 2.3, and add it to the
documentation.  HINT HINT.  If you want a PEP first, I'll write one, but
this just looks like a bugfix to me.

  PIL has a fast crop() method, but it then throws away the transparency
information, making it useless to me.  I'm not that familiar with PIL,
but the obvious way to use it does not work, the documentation is
uninformative on the problem, and according to google, people who've
previously asked similar questions have received no answers.

  I need answers.

  I'd rather have a fixed Tkinter than PIL, since getting users to
install more libraries sucks and I have no need for PIL's other
features, but I'll take what I can get.

  Right now, I have the following code, and my images are all
transparent GIFs.

  Thanks in advance.

---cut here---
def getTileImagePIL(tile):
    key = getTile(tile)
    filename, tx, ty = key
    tx *= TILESIZE
    ty *= TILESIZE
    img = IMAGES.get(key)
    if not img:
        # get master image
        bitmap = IMAGES.get(filename)
        if not bitmap:
            if DEBUG: Log.log('Loading %s' % filename)
            bitmap = Image.open(filename)
            pagename, width, height = getPagedata(filename)
            bitmapsize = bitmap.size
            if (width*TILESIZE != bitmapsize[0]
                    or height*TILESIZE != bitmapsize[1]):
                raise AssertionError, 'Image size mismatch: %s' % filename
            IMAGES[filename] = bitmap
        # get one tile from image
        subimage = bitmap.crop( (tx, ty, tx+TILESIZE, ty+TILESIZE) )
        img = ImageTk.PhotoImage(subimage)
        IMAGES[key] = img
    return img

def getTileImageTkinter(tile):
    key = getTile(tile)
    filename, tx, ty = key
    tx *= TILESIZE
    ty *= TILESIZE
    img = IMAGES.get(key)
    if not img:
        # get master image
        bitmap = IMAGES.get(filename)
        if not bitmap:
            if DEBUG: Log.log('Loading %s' % filename)
            bitmap = Tkinter.PhotoImage(file=filename)
            pagename, width, height = getPagedata(filename)
            if (width*TILESIZE != bitmap.width()
                    or height*TILESIZE != bitmap.height()):
                raise AssertionError, 'Image size mismatch: %s' % filename
            IMAGES[filename] = bitmap
        # get one tile from image
        try:
            bitmap.write('tmp.gif', format='GIF',
                    from_coords=(tx, ty, tx+TILESIZE, ty+TILESIZE) )
        except Tkinter.TclError:
            Log.log('TclError, coords %d,%d-%d,%d in %d,%d' % (tx, ty,
                    tx+TILESIZE, ty+TILESIZE, bitmap.width(), bitmap.height()) )
            raise
        img = Tkinter.PhotoImage(file='tmp.gif')
        IMAGES[key] = img
    return img

try:
    import Image, ImageTk
    PIL = True
    getTileImage = getTileImagePIL
except ImportError:
    import Tkinter, tkMessageBox
    PIL = False
    getTileImage = getTileImageTkinter
---cut here---

-- 
 <a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
"The computer is incredibly fast, accurate, and stupid.
 Man is unbelievably slow, inaccurate, and brilliant.
 The marriage of the two is a force beyond calculation." -Leo Cherne




More information about the Python-list mailing list