#----------------------------------------------------------------------
# Name: ImageStore.py
# Purpose: Centralised loading of images, supports different
# methods of loading: image files, zip files and modules
#
# Author: Riaan Booysen
#
# Created: 2000/03/15
# RCS-ID: $Id: ImageStore.py,v 1.19 2007/07/02 15:01:04 riaan Exp $
# Copyright: (c) 1999 - 2007 Riaan Booysen
# Licence: BSD
#----------------------------------------------------------------------
import sys, os, cStringIO
import wx
_ = wx.GetTranslation
class ImageStoreError(Exception): pass
class InvalidImgPathError(ImageStoreError): pass
class UnhandledExtError(ImageStoreError): pass
class ImageStore:
Error = ImageStoreError
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])
bitmap = wx.BitmapFromImage(wx.ImageFromStream(stream))
if filename[-3:].lower() == 'ico':
icon = wx.EmptyIcon()
icon.CopyFromBitmap(bitmap)
return icon
else:
return bitmap
else:
raise UnhandledExtError, _('Extension not handled: %s')%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 name in self.dataReg:
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 canonizePath(self, imgPath):
return os.path.normpath(imgPath).replace('\\', '/')
def checkPath(self, imgPath):
if imgPath in self.dataReg:
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 imgPath in self.archives[archive]:
if imgPath[-1] == '/':
continue
imgData = zf.read(imgPath)
self.registerImage(imgPath, imgData)
zf.close()
else:
print 'image archive %s not found'%archive
def load(self, name):
name = self.canonizePath(name)
if name in self.dataReg:
return self.createImage(name, 'data')
else:
return ImageStore.load(self, name)
class ResourceImageStore(ImageStore):
def __init__(self, rootpaths, images=None, cache=1):
ImageStore.__init__(self, rootpaths, images, cache)
def subModuleImport(self, name):
realSysPath = sys.path
try:
for path in self.rootpaths:
sys.path = [path]
try:
mod = __import__(name)
except ImportError:
continue
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
raise ImportError, _('Could not find %s')%name
finally:
sys.path = realSysPath
def load(self, pathName):
name = self.transformPathToModuleSpace(pathName)
if name not in self.dataReg:
try:
mod = self.subModuleImport(name)
except ImportError, err:
#print '%s not found: %s'%(name, str(err))
return ImageStore.load(self, pathName)
self.dataReg[name] = mod.data
return ImageStore.load(self, name)
def registerImage(self, name, data):
name = self.transformPathToModuleSpace(name)
ImageStore.registerImage(self, name, data)
def transformPathToModuleSpace(self, name):
name = self.canonizePath(name)
name = name.replace('.', '_').replace('/', '.')
return name
ImageStoreClasses = {
'files': ImageStore,
'zip' : ZippedImageStore,
'resource': ResourceImageStore,
}
|