Tkinter PhotoImage or PIL transparent subimages

  • Thread starter Mark 'Kamikaze' Hughes
  • Start date
M

Mark 'Kamikaze' Hughes

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top