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) # 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 img2py.py -- Convert an image to PNG format and embed it in a Python
@@ -38,10 +41,12 @@ Options:
fucntions, (getNameBitmap, etc.) fucntions, (getNameBitmap, etc.)
-c Maintain a catalog of names that can be used to reference -c Maintain a catalog of names that can be used to reference
images. Catalog can be accessed via catalog and index attributes images. Catalog can be accessed via catalog and
of the module. If the -n <name> option is specified then <name> index attributes of the module.
If the -n <name> option is specified then <name>
is used for the catalog key and index value, otherwise 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 -a This flag specifies that the python_file should be appended
to instead of overwritten. This in combination with -n will 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. -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) # 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 cPickle
import cStringIO import cStringIO
import getopt import getopt
import glob import glob
import os import os
import os.path
import sys import sys
import tempfile import tempfile
import zlib import zlib
import re
import wx import wx
import img2img 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. # This next bit is borrowed from PIL. It is used to wrap the text intelligently.
fp = cStringIO.StringIO() fp = cStringIO.StringIO()
data = data + " " # buffer for the +1 test data += " " # buffer for the +1 test
c = i = 0 c = i = 0
word = "" word = ""
octdigits = "01234567" octdigits = "01234567"
@@ -95,52 +113,198 @@ def crunch_data(data, compressed):
while i < len(data): while i < len(data):
if data[i] != "\\": if data[i] != "\\":
word = data[i] word = data[i]
i = i + 1 i += 1
else: else:
if data[i+1] in octdigits: 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: if data[i+n] not in octdigits:
break break
word = data[i:i+n] word = data[i:i+n]
i = i + n i += n
elif data[i+1] == 'x': elif data[i+1] == 'x':
for n in range(2, 5): for n in xrange(2, 5):
if data[i+n] not in hexdigits: if data[i+n] not in hexdigits:
break break
word = data[i:i+n] word = data[i:i+n]
i = i + n i += n
else: else:
word = data[i:i+2] word = data[i:i+2]
i = i + 2 i += 2
l = len(word) l = len(word)
if c + l >= 78-1: if c + l >= 78-1:
fp.write("\\\n") fp.write("\\\n")
c = 0 c = 0
fp.write(word) fp.write(word)
c = c + l c += l
# return the formatted compressed data # return the formatted compressed data
return fp.getvalue() return fp.getvalue()
app = None 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): def main(args):
if not args or ("-h" in args): if not args or ("-h" in args):
print __doc__ print __doc__
return return
# some bitmap related things need to have a wxApp initialized... append = DEFAULT_APPEND
if wx.GetApp() is None: compressed = DEFAULT_COMPRESSED
global app maskClr = DEFAULT_MASKCLR
app = wx.PySimpleApp() imgName = DEFAULT_IMGNAME
icon = DEFAULT_ICON
append = 0 catalog = DEFAULT_CATALOG
compressed = 1
maskClr = None
imgName = ""
icon = 0
catalog = 0
try: try:
opts, fileArgs = getopt.getopt(args, "auicn:m:") opts, fileArgs = getopt.getopt(args, "auicn:m:")
@@ -150,131 +314,26 @@ def main(args):
for opt, val in opts: for opt, val in opts:
if opt == "-a": if opt == "-a":
append = 1 append = True
elif opt == "-u": elif opt == "-u":
compressed = 0 compressed = False
elif opt == "-n": elif opt == "-n":
imgName = val imgName = val
elif opt == "-m": elif opt == "-m":
maskClr = val maskClr = val
elif opt == "-i": elif opt == "-i":
icon = 1 icon = True
elif opt == "-c": elif opt == "-c":
catalog = 1 catalog = True
if len(fileArgs) != 2: if len(fileArgs) != 2:
print __doc__ print __doc__
return return
image_file, python_file = fileArgs 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__": if __name__ == "__main__":
main(sys.argv[1:]) main(sys.argv[1:])