#!/usr/bin/env python """ 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.) -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. """ import sys, os, glob, getopt, tempfile, string import cPickle, cStringIO, zlib import img2img from wxPython import wx 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 append = 0 compressed = 1 maskClr = None imgName = "" icon = 0 try: opts, fileArgs = getopt.getopt(args, "auin: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 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.wxBITMAP_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") out.write("#" + "-" * 70 + "\n") if not append: out.write("# This file was generated by %s\n#\n" % sys.argv[0]) out.write("from wxPython.wx import wxImageFromStream, wxBitmapFromImage\n") if icon: out.write("from wxPython.wx import wxEmptyIcon\n") if compressed: out.write("import cStringIO, zlib\n\n\n") else: out.write("import cStringIO\n\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 %s\n\n" % (imgName, data)) out.write("def get%sBitmap():\n" " return wxBitmapFromImage(get%sImage())\n\n" "def get%sImage():\n" " stream = cStringIO.StringIO(get%sData())\n" " return wxImageFromStream(stream)\n\n" % tuple([imgName] * 4)) if icon: out.write("def get%sIcon():\n" " icon = wxEmptyIcon()\n" " icon.CopyFromBitmap(get%sBitmap())\n" " return icon\n\n" % tuple([imgName] * 2)) 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:])