I use this utility to generate an "images.py" module which I use to provide images to my applications via wx.ImageFromStream . You can see an output in my other recipe "A foldable panel with a Windows XP look and feel". The utility is called "convert.py" and can be put in a folder together with the png images. When run, it'll generate the "images.py" file which can be moved to wherever it'll be used. The only thing I'm checking for is that "convert.py" won't overwrite an existing "images.py" file in the same directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import sys
import os
import binascii
from glob import glob
s_header="""import wx
from cStringIO import StringIO
from binascii import a2b_base64
class Images:
def __init__(self):
for name in _names:
img = wx.ImageFromStream(StringIO(a2b_base64(eval(\"_\"+name))))
img.ConvertAlphaToMask(100)
exec(\"self.bmp_\"+name+\"=img.ConvertToBitmap()\")
self._names=_names\n
"""
max_line=78
def split_string(s):
ls=len(s)
so=""
while len(s)>max_line-1:
so+=s[:max_line-1]+"\\\n"
s=s[max_line-1:]
so+=s
return so
def split_list(s):
b=s
s_out=""
while(len(b)>max_line):
c=b[0:max_line]
tail,head=c[::-1].split(",",1)
head,tail=head[::-1],tail[::-1]
s_out+=head+",\n"
b=" "+tail+b[max_line:]
s_out+=b
return s_out
def convert_base64(s,var_name):
so=binascii.b2a_base64(s)
print "converting %s: %d->%d" % (var_name,len(s),len(so))
r_out="%s=\"" % var_name
r_out+=so[:-1]+"\""
return r_out
def convert(s,var_name):
l=len(s)
print "converting %s (%d chars)" % (var_name,l)
r_out="%s=\"" % var_name
for c in s:
o=ord(c)
if c=="\"":
c_out="\\\""
elif c=="\'":
c_out="\\\'"
elif c=="\\":
c_out="\\\\"
elif o>31 and o<127:
c_out=c
elif o<16:
c_out="\\x0"+hex(o)[2:]
else:
c_out="\\x"+hex(o)[2:]
r_out+=c_out
r_out+="\""
return r_out
def main(argv=None):
#for the time being, get the list from glob...
png_files=glob(os.path.join(".",'*.png'))
v_list=[]
s_vars=""
for fn in png_files:
s=open(fn,"rb").read()
p,fn=os.path.split(fn)
v=fn[:-4]
v=v.replace("stock_","")
v=v.replace("3d-","")
v=v.replace("-16","")
v=v.replace("-","_")
v=v.replace(" ","_")
v=v.replace(".","_")
v_list.append(v)
r=split_string(convert_base64(s,"_"+v))
s_vars+=r+"\n\n"
s_names=split_list("_names="+str(v_list))+"\n\n"
if os.path.exists("images.py"):
try:
os.rename("images.py","images.bak")
print "Your old images.py was renamed images.bak"
except:
print "Sorry, I don\'t do deletes..."
print "Please delete images.bak yourself"
f=open("images.py","w")
f.write(s_header)
f.write(s_names)
f.write(s_vars)
f.close()
if __name__ == '__main__':
main()
|
The max_line variable defines the lines length for the image data.
readability of identifiers. I mean, there will be one more line after last [v=v.replace(".","_")]:
Yes, that is useful. Converts multiple underscores into single ones. I'll rework my string manipulation code but I think my program should come with a fair warning: "if possible, clean the filenames as much as you can before running the program".
The main reason for the code is to process the openoffice icons (see http://www.novell.com/coolsolutions/feature/1637.html for a zip/tarball).
Their (stock) filenames come as something like "stock_data-save.png" which need to be cleaned-up a bit before they can be used as variable names.
If I get a sec, I'll turn the filename->variable name conversion bit of code into a cookbook recipe (which won't span over 300 lines for a change!)
Cheers, Egor