X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1fded56b375bf7a4687af1cdb182899614c1b2a8..c18f141ad00ed43c69541c43d318314b5fd129b2:/wxPython/wx/tools/img2py.py diff --git a/wxPython/wx/tools/img2py.py b/wxPython/wx/tools/img2py.py index de1d5e2a58..b4f6b4c9e4 100644 --- a/wxPython/wx/tools/img2py.py +++ b/wxPython/wx/tools/img2py.py @@ -1,11 +1,279 @@ +#---------------------------------------------------------------------- +# Name: wxPython.tools.img2py +# Purpose: Convert an image to Python code. +# +# Author: Robin Dunn +# +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- +# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net) +# +# o V2.5 compatability update +# -"""Renamer stub: provides a way to drop the wx prefix from wxPython objects.""" -__cvsid__ = "$Id$" -__revision__ = "$Revision$"[11:-2] +""" +img2py.py -- Convert an image to PNG format and embed it in a Python + module with appropriate code so it can be loaded into + a program at runtime. The benefit is that since it is + Python source code it can be delivered as a .pyc or + 'compiled' into the program using freeze, py2exe, etc. + +Usage: + + img2py.py [options] image_file python_file + +Options: + + -m <#rrggbb> If the original image has a mask or transparency defined + it will be used by default. You can use this option to + override the default or provide a new mask by specifying + a colour in the image to mark as transparent. + + -n Normally generic names (getBitmap, etc.) are used for the + image access functions. If you use this option you can + specify a name that should be used to customize the access + fucntions, (getNameBitmap, etc.) + + -c Maintain a catalog of names that can be used to reference + images. Catalog can be accessed via catalog and index attributes + of the module. If the -n option is specified then + is used for the catalog key and index value, otherwise + the filename without any path or extension is used as the key. + + -a This flag specifies that the python_file should be appended + to instead of overwritten. This in combination with -n will + allow you to put multiple images in one Python source file. + + -u Don't use compression. Leaves the data uncompressed. + + -i Also output a function to return the image as a wxIcon. + +""" + +# +# Changes: +# - Cliff Wells +# 20021206: Added catalog (-c) option. +# +# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net) +# +# o V2.5 compatability update +# + +import cPickle +import cStringIO +import getopt +import glob +import os +import sys +import tempfile +import zlib + +import wx + +import img2img + + +def crunch_data(data, compressed): + # compress it? + if compressed: + data = zlib.compress(data, 9) + + # convert to a printable format, so it can be in a Python source file + data = repr(data) + + # This next bit is borrowed from PIL. It is used to wrap the text intelligently. + fp = cStringIO.StringIO() + data = data + " " # buffer for the +1 test + c = i = 0 + word = "" + octdigits = "01234567" + hexdigits = "0123456789abcdef" + while i < len(data): + if data[i] != "\\": + word = data[i] + i = i + 1 + else: + if data[i+1] in octdigits: + for n in range(2, 5): + if data[i+n] not in octdigits: + break + word = data[i:i+n] + i = i + n + elif data[i+1] == 'x': + for n in range(2, 5): + if data[i+n] not in hexdigits: + break + word = data[i:i+n] + i = i + n + else: + word = data[i:i+2] + i = i + 2 + + l = len(word) + if c + l >= 78-1: + fp.write("\\\n") + c = 0 + fp.write(word) + c = c + l + + # return the formatted compressed data + return fp.getvalue() + + + +def main(args): + if not args or ("-h" in args): + print __doc__ + return + + # some bitmap related things need to have a wxApp initialized... + if wx.GetApp() is None: + app = wx.PySimpleApp() + + append = 0 + compressed = 1 + maskClr = None + imgName = "" + icon = 0 + catalog = 0 + + try: + opts, fileArgs = getopt.getopt(args, "auicn:m:") + except getopt.GetoptError: + print __doc__ + return + + for opt, val in opts: + if opt == "-a": + append = 1 + elif opt == "-u": + compressed = 0 + elif opt == "-n": + imgName = val + elif opt == "-m": + maskClr = val + elif opt == "-i": + icon = 1 + elif opt == "-c": + catalog = 1 + + if len(fileArgs) != 2: + print __doc__ + return + + image_file, python_file = fileArgs + + # convert the image file to a temporary file + tfname = tempfile.mktemp() + ok, msg = img2img.convert(image_file, maskClr, None, tfname, wx.BITMAP_TYPE_PNG, ".png") + if not ok: + print msg + return + + data = open(tfname, "rb").read() + data = crunch_data(data, compressed) + os.unlink(tfname) + + if append: + out = open(python_file, "a") + else: + out = open(python_file, "w") + + if catalog: + pyPath, pyFile = os.path.split(python_file) + imgPath, imgFile = os.path.split(image_file) + + if not imgName: + imgName = os.path.splitext(imgFile)[0] + print "\nWarning: -n not specified. Using filename (%s) for catalog entry." % imgName + + old_index = [] + if append: + # check to see if catalog exists already (file may have been created + # with an earlier version of img2py or without -c option) + oldSysPath = sys.path[:] + sys.path = [pyPath] # make sure we don't import something else by accident + mod = __import__(os.path.splitext(pyFile)[0]) + if 'index' not in dir(mod): + print "\nWarning: %s was originally created without catalog." % python_file + print " Any images already in file will not be cataloged.\n" + out.write("\n# ***************** Catalog starts here *******************") + out.write("\n\ncatalog = {}\n") + out.write("index = []\n\n") + out.write("class ImageClass: pass\n\n") + else: # save a copy of the old index so we can warn about duplicate names + old_index[:] = mod.index[:] + del mod + sys.path = oldSysPath[:] + + out.write("#" + "-" * 70 + "\n") + if not append: + out.write("# This file was generated by %s\n#\n" % sys.argv[0]) + out.write("from wx import ImageFromStream, BitmapFromImage\n") + if icon: + out.write("from wx import EmptyIcon\n") + if compressed: + out.write("import cStringIO, zlib\n\n\n") + else: + out.write("import cStringIO\n\n\n") + + if catalog: + out.write("catalog = {}\n") + out.write("index = []\n\n") + out.write("class ImageClass: pass\n\n") + + if compressed: + out.write("def get%sData():\n" + " return zlib.decompress(\n%s)\n\n" + % (imgName, data)) + else: + out.write("def get%sData():\n" + " return \\\n%s\n\n" + % (imgName, data)) + + + out.write("def get%sBitmap():\n" + " return BitmapFromImage(get%sImage())\n\n" + "def get%sImage():\n" + " stream = cStringIO.StringIO(get%sData())\n" + " return ImageFromStream(stream)\n\n" + % tuple([imgName] * 4)) + if icon: + out.write("def get%sIcon():\n" + " icon = EmptyIcon()\n" + " icon.CopyFromBitmap(get%sBitmap())\n" + " return icon\n\n" + % tuple([imgName] * 2)) + + if catalog: + if imgName in old_index: + print "Warning: %s already in catalog." % imgName + print " Only the last entry will be accessible.\n" + old_index.append(imgName) + out.write("index.append('%s')\n" % imgName) + out.write("catalog['%s'] = ImageClass()\n" % imgName) + out.write("catalog['%s'].getData = get%sData\n" % tuple([imgName] * 2)) + out.write("catalog['%s'].getImage = get%sImage\n" % tuple([imgName] * 2)) + out.write("catalog['%s'].getBitmap = get%sBitmap\n" % tuple([imgName] * 2)) + if icon: + out.write("catalog['%s'].getIcon = get%sIcon\n" % tuple([imgName] * 2)) + out.write("\n\n") + + if imgName: + n_msg = ' using "%s"' % imgName + else: + n_msg = "" + if maskClr: + m_msg = " with mask %s" % maskClr + else: + m_msg = "" + print "Embedded %s%s into %s%s" % (image_file, n_msg, python_file, m_msg) + + +if __name__ == "__main__": + main(sys.argv[1:]) -from wx import _rename -from wxPython.tools import img2py -_rename(globals(), img2py.__dict__, modulename='tools.img2py') -del img2py -del _rename