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:
@@ -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:])
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user