]> git.saurik.com Git - wxWidgets.git/blame_incremental - wxPython/wx/tools/img2py.py
Fix or add some DoGetBestSize's
[wxWidgets.git] / wxPython / wx / tools / img2py.py
... / ...
CommitLineData
1#----------------------------------------------------------------------
2# Name: wxPython.tools.img2py
3# Purpose: Convert an image to Python code.
4#
5# Author: Robin Dunn
6#
7# RCS-ID: $Id$
8# Copyright: (c) 2002 by Total Control Software
9# Licence: wxWindows license
10#----------------------------------------------------------------------
11# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
12#
13# o V2.5 compatability update
14#
15
16
17"""
18img2py.py -- Convert an image to PNG format and embed it in a Python
19 module with appropriate code so it can be loaded into
20 a program at runtime. The benefit is that since it is
21 Python source code it can be delivered as a .pyc or
22 'compiled' into the program using freeze, py2exe, etc.
23
24Usage:
25
26 img2py.py [options] image_file python_file
27
28Options:
29
30 -m <#rrggbb> If the original image has a mask or transparency defined
31 it will be used by default. You can use this option to
32 override the default or provide a new mask by specifying
33 a colour in the image to mark as transparent.
34
35 -n <name> Normally generic names (getBitmap, etc.) are used for the
36 image access functions. If you use this option you can
37 specify a name that should be used to customize the access
38 fucntions, (getNameBitmap, etc.)
39
40 -c Maintain a catalog of names that can be used to reference
41 images. Catalog can be accessed via catalog and index attributes
42 of the module. If the -n <name> option is specified then <name>
43 is used for the catalog key and index value, otherwise
44 the filename without any path or extension is used as the key.
45
46 -a This flag specifies that the python_file should be appended
47 to instead of overwritten. This in combination with -n will
48 allow you to put multiple images in one Python source file.
49
50 -u Don't use compression. Leaves the data uncompressed.
51
52 -i Also output a function to return the image as a wxIcon.
53
54"""
55
56#
57# Changes:
58# - Cliff Wells <LogiplexSoftware@earthlink.net>
59# 20021206: Added catalog (-c) option.
60#
61# 12/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)
62#
63# o V2.5 compatability update
64#
65
66import cPickle
67import cStringIO
68import getopt
69import glob
70import os
71import sys
72import tempfile
73import zlib
74
75import wx
76
77import img2img
78
79
80def crunch_data(data, compressed):
81 # compress it?
82 if compressed:
83 data = zlib.compress(data, 9)
84
85 # convert to a printable format, so it can be in a Python source file
86 data = repr(data)
87
88 # This next bit is borrowed from PIL. It is used to wrap the text intelligently.
89 fp = cStringIO.StringIO()
90 data = data + " " # buffer for the +1 test
91 c = i = 0
92 word = ""
93 octdigits = "01234567"
94 hexdigits = "0123456789abcdef"
95 while i < len(data):
96 if data[i] != "\\":
97 word = data[i]
98 i = i + 1
99 else:
100 if data[i+1] in octdigits:
101 for n in range(2, 5):
102 if data[i+n] not in octdigits:
103 break
104 word = data[i:i+n]
105 i = i + n
106 elif data[i+1] == 'x':
107 for n in range(2, 5):
108 if data[i+n] not in hexdigits:
109 break
110 word = data[i:i+n]
111 i = i + n
112 else:
113 word = data[i:i+2]
114 i = i + 2
115
116 l = len(word)
117 if c + l >= 78-1:
118 fp.write("\\\n")
119 c = 0
120 fp.write(word)
121 c = c + l
122
123 # return the formatted compressed data
124 return fp.getvalue()
125
126
127
128def main(args):
129 if not args or ("-h" in args):
130 print __doc__
131 return
132
133 # some bitmap related things need to have a wxApp initialized...
134 if wx.GetApp() is None:
135 app = wx.PySimpleApp()
136
137 append = 0
138 compressed = 1
139 maskClr = None
140 imgName = ""
141 icon = 0
142 catalog = 0
143
144 try:
145 opts, fileArgs = getopt.getopt(args, "auicn:m:")
146 except getopt.GetoptError:
147 print __doc__
148 return
149
150 for opt, val in opts:
151 if opt == "-a":
152 append = 1
153 elif opt == "-u":
154 compressed = 0
155 elif opt == "-n":
156 imgName = val
157 elif opt == "-m":
158 maskClr = val
159 elif opt == "-i":
160 icon = 1
161 elif opt == "-c":
162 catalog = 1
163
164 if len(fileArgs) != 2:
165 print __doc__
166 return
167
168 image_file, python_file = fileArgs
169
170 # convert the image file to a temporary file
171 tfname = tempfile.mktemp()
172 ok, msg = img2img.convert(image_file, maskClr, None, tfname, wx.BITMAP_TYPE_PNG, ".png")
173 if not ok:
174 print msg
175 return
176
177 data = open(tfname, "rb").read()
178 data = crunch_data(data, compressed)
179 os.unlink(tfname)
180
181 if append:
182 out = open(python_file, "a")
183 else:
184 out = open(python_file, "w")
185
186 if catalog:
187 pyPath, pyFile = os.path.split(python_file)
188 imgPath, imgFile = os.path.split(image_file)
189
190 if not imgName:
191 imgName = os.path.splitext(imgFile)[0]
192 print "\nWarning: -n not specified. Using filename (%s) for catalog entry." % imgName
193
194 old_index = []
195 if append:
196 # check to see if catalog exists already (file may have been created
197 # with an earlier version of img2py or without -c option)
198 oldSysPath = sys.path[:]
199 sys.path = [pyPath] # make sure we don't import something else by accident
200 mod = __import__(os.path.splitext(pyFile)[0])
201 if 'index' not in dir(mod):
202 print "\nWarning: %s was originally created without catalog." % python_file
203 print " Any images already in file will not be cataloged.\n"
204 out.write("\n# ***************** Catalog starts here *******************")
205 out.write("\n\ncatalog = {}\n")
206 out.write("index = []\n\n")
207 out.write("class ImageClass: pass\n\n")
208 else: # save a copy of the old index so we can warn about duplicate names
209 old_index[:] = mod.index[:]
210 del mod
211 sys.path = oldSysPath[:]
212
213 out.write("#" + "-" * 70 + "\n")
214 if not append:
215 out.write("# This file was generated by %s\n#\n" % sys.argv[0])
216 out.write("from wx import ImageFromStream, BitmapFromImage\n")
217 if icon:
218 out.write("from wx import EmptyIcon\n")
219 if compressed:
220 out.write("import cStringIO, zlib\n\n\n")
221 else:
222 out.write("import cStringIO\n\n\n")
223
224 if catalog:
225 out.write("catalog = {}\n")
226 out.write("index = []\n\n")
227 out.write("class ImageClass: pass\n\n")
228
229 if compressed:
230 out.write("def get%sData():\n"
231 " return zlib.decompress(\n%s)\n\n"
232 % (imgName, data))
233 else:
234 out.write("def get%sData():\n"
235 " return \\\n%s\n\n"
236 % (imgName, data))
237
238
239 out.write("def get%sBitmap():\n"
240 " return BitmapFromImage(get%sImage())\n\n"
241 "def get%sImage():\n"
242 " stream = cStringIO.StringIO(get%sData())\n"
243 " return ImageFromStream(stream)\n\n"
244 % tuple([imgName] * 4))
245 if icon:
246 out.write("def get%sIcon():\n"
247 " icon = EmptyIcon()\n"
248 " icon.CopyFromBitmap(get%sBitmap())\n"
249 " return icon\n\n"
250 % tuple([imgName] * 2))
251
252 if catalog:
253 if imgName in old_index:
254 print "Warning: %s already in catalog." % imgName
255 print " Only the last entry will be accessible.\n"
256 old_index.append(imgName)
257 out.write("index.append('%s')\n" % imgName)
258 out.write("catalog['%s'] = ImageClass()\n" % imgName)
259 out.write("catalog['%s'].getData = get%sData\n" % tuple([imgName] * 2))
260 out.write("catalog['%s'].getImage = get%sImage\n" % tuple([imgName] * 2))
261 out.write("catalog['%s'].getBitmap = get%sBitmap\n" % tuple([imgName] * 2))
262 if icon:
263 out.write("catalog['%s'].getIcon = get%sIcon\n" % tuple([imgName] * 2))
264 out.write("\n\n")
265
266 if imgName:
267 n_msg = ' using "%s"' % imgName
268 else:
269 n_msg = ""
270 if maskClr:
271 m_msg = " with mask %s" % maskClr
272 else:
273 m_msg = ""
274 print "Embedded %s%s into %s%s" % (image_file, n_msg, python_file, m_msg)
275
276
277if __name__ == "__main__":
278 main(sys.argv[1:])
279