Patch from Gianluca Costa:

-Refactorization of the script-creation code in a specific "img2py()" function
    -Added regex parsing instead of module importing
    -Added some "try/finally" statements
    -Added default values as named constants
    -Made some parts of code a bit easier to read
    -Updated the module docstring
    -Corrected a bug with EmptyIcon


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@44593 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2007-03-01 21:51:23 +00:00
parent 6b260f32ca
commit 99f22cf696

View File

@@ -10,9 +10,12 @@
#----------------------------------------------------------------------
# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o V2.5 compatability update
#
# 2/25/2007 - Gianluca Costa (archimede86@katamail.com)
#
#
# o V2.5 compatibility update
#
"""
img2py.py -- Convert an image to PNG format and embed it in a Python
@@ -38,10 +41,12 @@ Options:
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 <name> option is specified then <name>
images. Catalog can be accessed via catalog and
index attributes of the module.
If the -n <name> option is specified then <name>
is used for the catalog key and index value, otherwise
the filename without any path or extension is used as the key.
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
@@ -51,6 +56,9 @@ Options:
-i Also output a function to return the image as a wxIcon.
You can also import this module from your Python scripts, and use its img2py()
function. See its docstring for more info.
"""
#
@@ -60,20 +68,30 @@ Options:
#
# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o V2.5 compatability update
#
# 2/25/2007 - Gianluca Costa (archimede86@katamail.com)
# -Refactorization of the script-creation code in a specific "img2py()" function
# -Added regex parsing instead of module importing
# -Added some "try/finally" statements
# -Added default values as named constants
# -Made some parts of code a bit easier to read
# -Updated the module docstring
# -Corrected a bug with EmptyIcon
#
# o V2.5 compatibility update
#
import cPickle
import cStringIO
import getopt
import glob
import os
import os.path
import sys
import tempfile
import zlib
import re
import wx
import img2img
@@ -87,7 +105,7 @@ def crunch_data(data, compressed):
# 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
data += " " # buffer for the +1 test
c = i = 0
word = ""
octdigits = "01234567"
@@ -95,52 +113,198 @@ def crunch_data(data, compressed):
while i < len(data):
if data[i] != "\\":
word = data[i]
i = i + 1
i += 1
else:
if data[i+1] in octdigits:
for n in range(2, 5):
for n in xrange(2, 5):
if data[i+n] not in octdigits:
break
word = data[i:i+n]
i = i + n
i += n
elif data[i+1] == 'x':
for n in range(2, 5):
for n in xrange(2, 5):
if data[i+n] not in hexdigits:
break
word = data[i:i+n]
i = i + n
i += n
else:
word = data[i:i+2]
i = i + 2
i += 2
l = len(word)
if c + l >= 78-1:
fp.write("\\\n")
c = 0
fp.write(word)
c = c + l
c += l
# return the formatted compressed data
return fp.getvalue()
app = None
DEFAULT_APPEND = False
DEFAULT_COMPRESSED = True
DEFAULT_MASKCLR = None
DEFAULT_IMGNAME = ""
DEFAULT_ICON = False
DEFAULT_CATALOG = False
#THIS IS USED TO IDENTIFY, IN THE GENERATED SCRIPT, LINES IN THE FORM "index.append('Image name')"
indexPattern = re.compile(r"\s*index.append\('(.+)'\)\s*")
def img2py(image_file, python_file, append=DEFAULT_APPEND, compressed=DEFAULT_COMPRESSED, maskClr=DEFAULT_MASKCLR, imgName=DEFAULT_IMGNAME, icon=DEFAULT_ICON, catalog=DEFAULT_CATALOG):
"""
Converts an image file to a data structure written in a Python file
--image_file: string; the path of the source image file
--python_file: string; the path of the destination python file
--other arguments: they are equivalent to the command-line arguments
"""
global app
if not wx.GetApp():
app = wx.PySimpleApp()
# convert the image file to a temporary file
tfname = tempfile.mktemp()
try:
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)
finally:
if os.path.exists(tfname):
os.remove(tfname)
old_index = []
if catalog and append:
# check to see if catalog exists already (file may have been created
# with an earlier version of img2py or without -c option)
pyPath, pyFile = os.path.split(python_file)
append_catalog = True
sourcePy = open(python_file, "r")
try:
for line in sourcePy:
if line == "catalog = {}\n":
append_catalog = False
else:
lineMatcher = indexPattern.match(line)
if lineMatcher:
old_index.append(lineMatcher.groups()[0])
finally:
sourcePy.close()
if append_catalog:
out = open(python_file, "a")
try:
out.write("\n# ***************** Catalog starts here *******************")
out.write("\n\ncatalog = {}\n")
out.write("index = []\n\n")
out.write("class ImageClass: pass\n\n")
finally:
out.close()
if append:
out = open(python_file, "a")
else:
out = open(python_file, "w")
try:
if catalog:
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
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, 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)
finally:
out.close()
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:
global app
app = wx.PySimpleApp()
append = 0
compressed = 1
maskClr = None
imgName = ""
icon = 0
catalog = 0
append = DEFAULT_APPEND
compressed = DEFAULT_COMPRESSED
maskClr = DEFAULT_MASKCLR
imgName = DEFAULT_IMGNAME
icon = DEFAULT_ICON
catalog = DEFAULT_CATALOG
try:
opts, fileArgs = getopt.getopt(args, "auicn:m:")
@@ -150,131 +314,26 @@ def main(args):
for opt, val in opts:
if opt == "-a":
append = 1
append = True
elif opt == "-u":
compressed = 0
compressed = False
elif opt == "-n":
imgName = val
elif opt == "-m":
maskClr = val
elif opt == "-i":
icon = 1
icon = True
elif opt == "-c":
catalog = 1
catalog = True
if len(fileArgs) != 2:
print __doc__
return
image_file, python_file = fileArgs
img2py(image_file, python_file, append, compressed, maskClr, imgName, icon, catalog)
# 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:])