2001-04-09 19:36:36 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
"""
|
|
|
|
img2py.py -- Convert an image to XPM 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 <name> 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.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-04-27 00:16:02 +00:00
|
|
|
import sys, os, glob, getopt, tempfile, string
|
2001-04-09 19:36:36 +00:00
|
|
|
import cPickle, cStringIO, zlib
|
|
|
|
import img2xpm
|
|
|
|
|
|
|
|
|
|
|
|
def crunch_data(data, compressed):
|
2001-10-03 14:52:20 +00:00
|
|
|
# convert the lines to a Python list, pickle it and optionally compress the result.
|
2001-04-09 19:36:36 +00:00
|
|
|
lines = []
|
2001-04-27 00:16:02 +00:00
|
|
|
for line in data:
|
|
|
|
if line[0] == "\"":
|
|
|
|
# the line is typically (but not always):
|
|
|
|
# [quote] <data> [quote][comma][newline]
|
|
|
|
|
|
|
|
# chop one char from the front
|
|
|
|
line = line[1:]
|
|
|
|
|
|
|
|
# now find the final quote and truncate there
|
|
|
|
quote = string.rfind(line, "\"")
|
|
|
|
|
|
|
|
# and append the remaining data to our list
|
|
|
|
lines.append(line[:quote])
|
2001-04-09 19:36:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
# pickle, crunch and convert it to a form suitable for embedding in code
|
|
|
|
data = cPickle.dumps(lines)
|
|
|
|
if compressed:
|
|
|
|
data = zlib.compress(data, 9)
|
|
|
|
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"
|
2001-07-06 04:11:34 +00:00
|
|
|
hexdigits = "0123456789abcdef"
|
2001-04-09 19:36:36 +00:00
|
|
|
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
|
2001-07-06 04:11:34 +00:00
|
|
|
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
|
2001-04-09 19:36:36 +00:00
|
|
|
else:
|
|
|
|
word = data[i:i+2]
|
|
|
|
i = i + 2
|
2001-07-06 04:11:34 +00:00
|
|
|
|
2001-04-09 19:36:36 +00:00
|
|
|
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 = ""
|
|
|
|
|
|
|
|
try:
|
|
|
|
opts, fileArgs = getopt.getopt(args, "aun: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
|
|
|
|
|
|
|
|
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 = img2xpm.convert(image_file, maskClr, None, tfname)
|
|
|
|
if not ok:
|
|
|
|
print msg
|
|
|
|
return
|
|
|
|
|
|
|
|
data = open(tfname, "r").readlines()
|
|
|
|
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 wxBitmapFromXPMData, wxImageFromBitmap\n")
|
|
|
|
if compressed:
|
|
|
|
out.write("import cPickle, zlib\n\n\n")
|
|
|
|
else:
|
|
|
|
out.write("import cPickle\n\n\n")
|
|
|
|
|
|
|
|
if compressed:
|
|
|
|
out.write("def get%sData():\n"
|
|
|
|
" return cPickle.loads(zlib.decompress(\n%s))\n\n"
|
|
|
|
% (imgName, data))
|
|
|
|
else:
|
|
|
|
out.write("def get%sData():\n"
|
|
|
|
" return cPickle.loads(\n%s)\n\n"
|
|
|
|
% (imgName, data))
|
|
|
|
|
|
|
|
|
|
|
|
out.write("def get%sBitmap():\n"
|
|
|
|
" return wxBitmapFromXPMData(get%sData())\n\n"
|
|
|
|
"def get%sImage():\n"
|
|
|
|
" return wxImageFromBitmap(get%sBitmap())\n\n"
|
|
|
|
% tuple([imgName] * 4))
|
|
|
|
|
|
|
|
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:])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|