#---------------------------------------------------------------------- # Name: ImageStore.py # Purpose: Cache images used in a central place. # # Author: Riaan Booysen # # Created: 2000/03/15 # RCS-ID: $Id: ImageStore.py,v 1.15 2005/05/18 13:20:13 riaan Exp $ # Copyright: (c) 1999 - 2005 Riaan Booysen # Licence: BSD #---------------------------------------------------------------------- import os, cStringIO import wx class ImageStoreError(Exception): pass class InvalidImgPathError(ImageStoreError): pass class UnhandledExtError(ImageStoreError): pass class ImageStore: def __init__(self, rootpaths, images=None, cache=1): if not images: images = {} self.rootpaths = [] self.images = images self.useCache = cache self.dataReg = {} for rootpath in rootpaths: self.addRootPath(rootpath) def cleanup(self): self.images = {} self.dataReg = {} def createImage(self, filename, ext): if ext == '.bmp': return wx.Image(filename, wx.BITMAP_TYPE_BMP).ConvertToBitmap() elif ext == '.png': return wx.Image(filename, wx.BITMAP_TYPE_PNG).ConvertToBitmap() elif ext == '.jpg': return wx.Image(filename, wx.BITMAP_TYPE_JPEG).ConvertToBitmap() elif ext == '.gif': return wx.Image(filename, wx.BITMAP_TYPE_GIF).ConvertToBitmap() elif ext == '.ico': return wx.Icon(filename, wx.BITMAP_TYPE_ICO) elif ext == 'data': stream = cStringIO.StringIO(self.dataReg[filename]) return wx.BitmapFromImage(wx.ImageFromStream(stream)) else: raise UnhandledExtError, 'Extension not handled: '+ext def pathExtFromName(self, root, name): imgPath = self.canonizePath(os.path.join(root, name)) ext = os.path.splitext(name)[1] self.checkPath(imgPath) return imgPath, ext def load(self, name): if self.dataReg.has_key(name): return self.createImage(name, 'data') for rootpath in self.rootpaths: try: imgpath, ext = self.pathExtFromName(rootpath, name) except InvalidImgPathError: continue if self.useCache: if not self.images.has_key(name): self.images[name] = self.createImage(imgpath, ext) return self.images[name] else: return self.createImage(imgpath, ext) raise InvalidImgPathError, '%s not found in image paths' %name def canLoad(self, name): if self.dataReg.has_key(name): return 1 for rootpath in self.rootpaths: try: imgpath, ext = self.pathExtFromName(rootpath, name) except InvalidImgPathError: continue else: return 1 return 0 def canonizePath(self, imgPath): return os.path.normpath(imgPath).replace('\\', '/') def checkPath(self, imgPath): if self.dataReg.has_key(imgPath): return if not os.path.isfile(imgPath): raise InvalidImgPathError, '%s not valid' %imgPath def addRootPath(self, rootPath): self.rootpaths.append(rootPath) def registerImage(self, name, data): self.dataReg[name] = data class ZippedImageStore(ImageStore): def __init__(self, rootpaths, images=None, cache=1): self.archives = {} ImageStore.__init__(self, rootpaths, images, cache) def addRootPath(self, rootPath): ImageStore.addRootPath(self, rootPath) archive = os.path.join(rootPath, 'Images.archive.zip') if os.path.exists(archive): print 'reading Image archive...' import zipfile zf = zipfile.ZipFile(archive) self.archives[archive] = [fl.filename for fl in zf.filelist] for img in self.archives[archive]: if img[-1] == '/': continue imgData = zf.read(img) imgExt = os.path.splitext(img)[1] bmpPath = img self.images[bmpPath] = (imgData, imgExt) zf.close() def load(self, name): import tempfile name = self.canonizePath(name) try: imgData, imgExt = self.images[name] except KeyError: return ImageStore.load(self, name) else: tmpname = tempfile.mktemp() open(tmpname, 'wb').write(imgData) try: try: return self.createImage(tmpname, imgExt) except Exception, error: return ImageStore.load(self, name) finally: os.remove(tmpname) def canLoad(self, name): name = self.canonizePath(name) if not self.images.has_key(name): return ImageStore.canLoad(self, name) class ResourseImageStore(ImageStore): def __init__(self, rootpaths, images=None, cache=1): self.resources = {} ImageStore.__init__(self, rootpaths, images, cache)