~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to plug-ins/pygimp/plug-ins/py-slice.py

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
#Copyright (c) Manish Singh
 
5
#javascript animation support by Joao S. O. Bueno Calligaris (2004)
2
6
 
3
7
#   Gimp-Python - allows the writing of Gimp plugins in Python.
4
8
#   Copyright (C) 2003, 2005  Manish Singh <yosh@gimp.org>
17
21
#   along with this program; if not, write to the Free Software
18
22
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
23
 
 
24
# (c) 2003 Manish Singh.
 
25
#"Guillotine implemented ala python, with html output
 
26
# (based on perlotine by Seth Burgess)",
 
27
# Modified by João S. O. Bueno Calligaris to allow  dhtml animations (2005)
 
28
 
20
29
import os
21
30
 
22
 
import gimp
23
31
from gimpfu import *
 
32
import os.path
 
33
 
 
34
gettext.install("gimp20-python", gimp.locale_directory, unicode=True)
24
35
 
25
36
def pyslice(image, drawable, save_path, html_filename,
26
37
            image_basename, image_extension, separate,
27
 
            image_path, capitalize, cellspacing):
 
38
            image_path, cellspacing, animate, skip_caps):
 
39
    if animate:
 
40
        count = 0
 
41
        drw = []
 
42
        #image.layers is a reversed list of the layers on the image
 
43
        #so, count indexes from number of layers to 0.
 
44
        for i in xrange (len (image.layers) -1, -1, -1):
 
45
            if image.layers[i].visible:
 
46
                drw.append(image.layers[i])
 
47
                count += 1
 
48
                if count == 3:
 
49
                    break
 
50
 
28
51
 
29
52
    vert, horz = get_guides(image)
30
53
 
31
54
    if len(vert) == 0 and len(horz) == 0:
32
55
        return
33
56
 
34
 
    gimp.progress_init("Py-Slice")
 
57
    gimp.progress_init(_("Slice"))
35
58
    progress_increment = 1 / ((len(horz) + 1) * (len(vert) + 1))
36
59
    progress = 0.0
37
60
 
42
65
            os.mkdir(path)
43
66
 
44
67
        return path
45
 
    
 
68
 
46
69
    save_path = check_path(save_path)
47
70
 
48
71
    if not os.path.isdir(save_path):
50
73
 
51
74
    if separate:
52
75
        image_relative_path = image_path
 
76
        if not image_relative_path.endswith("/"):
 
77
            image_relative_path += "/"
53
78
        image_path = check_path(os.path.join(save_path, image_path))
54
79
    else:
55
80
        image_relative_path = ''
56
81
        image_path = save_path
57
82
 
58
83
    tw = TableWriter(os.path.join(save_path, html_filename),
59
 
                     cellspacing=cellspacing, capitalize=capitalize)
 
84
                     cellspacing=cellspacing, animate=animate)
60
85
 
61
86
    top = 0
62
87
 
75
100
                right = image.width
76
101
            else:
77
102
                right = image.get_guide_position(vert[j])
78
 
 
79
 
            src = slice(image, image_path, image_basename, image_extension,
80
 
                        left, right, top, bottom, i, j)
81
 
 
82
 
            if image_relative_path:
83
 
                if image_relative_path.endswith('/'):
84
 
                    src_path = image_relative_path + src
85
 
                else:
86
 
                    src_path = image_relative_path + '/' + src
87
 
            else:
88
 
                src_path = src
89
 
 
90
 
            tw.cell(src_path, right - left, bottom - top)
 
103
            if (skip_caps   and
 
104
                 (
 
105
                   (len(horz) >= 2 and (i == 0 or i == len(horz) )) or
 
106
                   (len(vert) >= 2 and (j == 0 or j == len(vert) ))
 
107
                 )
 
108
               ):
 
109
                skip_stub = True
 
110
            else:
 
111
                skip_stub = False
 
112
 
 
113
            if (not animate or skip_stub):
 
114
                src = (image_relative_path +
 
115
                       slice (image, None, image_path,
 
116
                              image_basename, image_extension,
 
117
                              left, right, top, bottom, i, j, ""))
 
118
            else:
 
119
                src = []
 
120
                for layer, postfix in zip (drw, ("", "hover", "clicked")):
 
121
                    src.append (image_relative_path +
 
122
                                slice(image, layer, image_path,
 
123
                                      image_basename, image_extension,
 
124
                                      left, right, top, bottom, i, j, postfix))
 
125
 
 
126
            tw.cell(src, right - left, bottom - top, i, j, skip_stub)
91
127
 
92
128
            left = right + cellspacing
93
129
 
100
136
 
101
137
    tw.close()
102
138
 
103
 
def slice(image, image_path, image_basename, image_extension,
104
 
          left, right, top, bottom, i, j):
105
 
    src = "%s-%d-%d.%s" % (image_basename, i, j, image_extension)
 
139
def slice(image, drawable, image_path, image_basename, image_extension,
 
140
          left, right, top, bottom, i, j, postfix):
 
141
    if postfix:
 
142
        postfix = "_" + postfix
 
143
    src = "%s_%d_%d%s.%s" % (image_basename, i, j, postfix, image_extension)
106
144
    filename = os.path.join(image_path, src)
107
145
 
108
 
    temp_image = image.duplicate()
 
146
    if not drawable:
 
147
        temp_image = image.duplicate()
 
148
        temp_drawable = temp_image.active_layer
 
149
    else:
 
150
        if image.base_type == INDEXED:
 
151
            #gimp_layer_new_from_drawable doesn't work for indexed images.
 
152
            #(no colormap on new images)
 
153
            original_active = image.active_layer
 
154
            image.active_layer = drawable
 
155
            temp_image = image.duplicate()
 
156
            temp_drawable = temp_image.active_layer
 
157
            image.active_layer = original_active
 
158
            temp_image.disable_undo()
 
159
            #remove all layers but the intended one
 
160
            while len (temp_image.layers) > 1:
 
161
                if temp_image.layers[0] != temp_drawable:
 
162
                    pdb.gimp_image_remove_layer (temp_image, temp_image.layers[0])
 
163
                else:
 
164
                    pdb.gimp_image_remove_layer (temp_image, temp_image.layers[1])
 
165
        else:
 
166
            temp_image = pdb.gimp_image_new (drawable.width, drawable.height,
 
167
                                         image.base_type)
 
168
            temp_drawable = pdb.gimp_layer_new_from_drawable (drawable, temp_image)
 
169
            temp_image.add_layer (temp_drawable, -1)
 
170
 
109
171
    temp_image.disable_undo()
110
 
 
111
172
    temp_image.crop(right - left, bottom - top, left, top)
112
 
 
113
 
    pdb.gimp_file_save(temp_image, temp_image.active_layer, filename, filename)
114
 
 
 
173
    if image_extension == "gif" and image.base_type == RGB:
 
174
        pdb.gimp_image_convert_indexed (temp_image,NO_DITHER, MAKE_PALETTE, 255,
 
175
                                        True, False, False)
 
176
    if image_extension == "jpg" and image.base_type == INDEXED:
 
177
        pdb.gimp_image_convert_rgb (temp_image)
 
178
    
 
179
    pdb.gimp_file_save(temp_image, temp_drawable, filename, filename)        
 
180
        
115
181
    gimp.delete(temp_image)
116
 
 
117
182
    return src
118
183
 
119
184
class GuideIter:
158
223
 
159
224
class TableWriter:
160
225
    def __init__(self, filename, cellpadding=0, cellspacing=0, border=0,
161
 
                 capitalize=FALSE):
 
226
                 animate=False):
 
227
 
 
228
        self.filename = filename
162
229
        self.table_attrs = {}
163
230
 
 
231
        #Hellraisen IE 6 doesn't support CSS for table control.
164
232
        self.table_attrs['cellpadding'] = cellpadding
165
233
        self.table_attrs['cellspacing'] = cellspacing
166
234
        self.table_attrs['border'] = border
167
235
 
168
 
        self.capitalize = capitalize
169
 
 
170
 
        self.html = file(filename, 'w')
171
 
 
 
236
        self.image_prefix = os.path.basename (filename)
 
237
        self.image_prefix = self.image_prefix.split(".")[0]
 
238
        self.image_prefix = self.image_prefix.replace ("-", "_")
 
239
        self.image_prefix = self.image_prefix.replace (" ", "_")
 
240
 
 
241
        
 
242
        if animate:
 
243
            self.animate = True
 
244
            self.images = []
 
245
        else:
 
246
            self.animate = False
 
247
 
 
248
        if os.path.exists (filename):
 
249
            #The plug-in is running to overwrite a previous
 
250
            #version of the file. This will parse the href targets already
 
251
            #in the file to preserve them.
 
252
            self.urls = self.parse_urls ()
 
253
        else:
 
254
            self.urls = []
 
255
            
 
256
        self.url_index = 0
 
257
        
 
258
        self.html = open(filename, 'wt')    
172
259
        self.open()
 
260
    
 
261
    def next_url (self):
 
262
        if self.url_index < len (self.urls):
 
263
            self.url_index += 1
 
264
            return self.urls [self.url_index - 1]
 
265
        else:
 
266
            #Default url to use in the anchor tags:
 
267
            return ("#")
173
268
 
174
269
    def write(self, s, vals=None):
175
 
        if self.capitalize:
176
 
            s = s.upper()
177
 
            s = s.replace('%S', '%s')
178
 
        else:
179
 
            s = s.lower()
180
 
 
181
270
        if vals:
182
271
            s = s % vals
183
272
 
184
273
        self.html.write(s + '\n')
185
274
 
186
275
    def open(self):
187
 
        out = '<table'
 
276
        out = '''<!--HTML SNIPPET GENERATED BY THE GIMP
 
277
 
 
278
WARNING!! This is NOT a fully valid HTML document, it is rather a piece of
 
279
HTML generated by the GIMP's py-slice plugin that should be embedded in an HTML
 
280
or XHTML document to be valid.
 
281
 
 
282
Replace the href targets in the anchor (<a >) for your URLS to have it working
 
283
as a menu.
 
284
 -->\n'''
 
285
        out += '<table'
188
286
 
189
287
        for attr, value in self.table_attrs.iteritems():
190
 
            out += ' %s=%s' % (attr, value)
 
288
            out += ' %s="%s"' % (attr, value)
191
289
 
192
290
        out += '>'
193
291
 
194
292
        self.write(out)
195
293
 
196
294
    def close(self):
197
 
        self.write('</table>')
198
 
        self.html.close()
 
295
        self.write('</table>\n')
 
296
        prefix = self.image_prefix
 
297
        if self.animate:
 
298
            out = """
 
299
<script language="javascript" type="text/javascript">
 
300
/* Made with The GIMP */
 
301
 
 
302
/* Preload images: */
 
303
    images_%s = new Array();
 
304
                   \n"""    % prefix
 
305
            for image in self.images:
 
306
                for type_ in ("plain", "hover", "clicked"):
 
307
                    if image.has_key(type_):
 
308
                        image_index = ("%d_%d_%s" %
 
309
                                       (image["index"][0],
 
310
                                        image["index"][1], type_))
 
311
                        out += ("    images_%s[\"%s\"] = new  Image();\n" %
 
312
                                (prefix, image_index))
 
313
                        out += ("    images_%s[\"%s\"].src = \"%s\";\n" %
 
314
                            (prefix, image_index, image[type_]))
 
315
 
 
316
            out+= """
 
317
function exchange (image, images_array_name, event)
 
318
  {
 
319
    name = image.name;
 
320
    images = eval (images_array_name);
 
321
 
 
322
    switch (event)
 
323
      {
 
324
        case 0:
 
325
          image.src = images[name + "_plain"].src;
 
326
          break;
 
327
        case 1:
 
328
          image.src = images[name + "_hover"].src;
 
329
          break;
 
330
        case 2:
 
331
          image.src = images[name + "_clicked"].src;
 
332
          break;
 
333
        case 3:
 
334
          image.src = images[name + "_hover"].src;
 
335
          break;
 
336
      }
 
337
 
 
338
  }
 
339
</script>
 
340
<!--
 
341
End of the part generated by the GIMP
 
342
-->
 
343
"""
 
344
            self.write (out)
 
345
 
199
346
 
200
347
    def row_start(self):
201
 
        self.write('\t<tr>')
 
348
        self.write('  <tr>')
202
349
 
203
350
    def row_end(self):
204
 
        self.write('\t</tr>')
205
 
 
206
 
    def cell(self, src, width, height):
207
 
        out = ('\t\t<td><img alt=" " src="%%s" width="%d" height="%d"></td>' %
208
 
               (width, height))
209
 
        self.write(out, src)
 
351
        self.write('</tr>\n')
 
352
 
 
353
    def cell(self, src, width, height, row=0, col=0, skip_stub = False):
 
354
        if isinstance (src, list):
 
355
            prefix = "images_%s" % self.image_prefix
 
356
            self.images.append ({"index" : (row, col), "plain" : src[0]})
 
357
 
 
358
            out = ('    <td><a href="%s"><img alt="" src="%s" ' +
 
359
                  'style="width: %dpx; height: %dpx; border-width: 0px" \n') %\
 
360
                  (self.next_url(), src[0], width, height)
 
361
            out += 'name="%d_%d" \n' % (row, col)
 
362
            if len(src) >= 2:
 
363
                self.images[-1]["hover"] = src [1]
 
364
                out += """      onmouseout="exchange(this, '%s', 0);"\n""" % \
 
365
                       prefix
 
366
                out += """      onmouseover="exchange(this, '%s', 1);"\n""" % \
 
367
                       prefix
 
368
            if len(src) >= 3:
 
369
                self.images[-1]["clicked"] = src [2]
 
370
                out += """      onmousedown="exchange(this, '%s', 2);"\n""" % \
 
371
                       prefix
 
372
                out += """      onmouseup="exchange(this, '%s', 3);"\n""" % \
 
373
                       prefix
 
374
 
 
375
 
 
376
 
 
377
            out += "/></a></td>\n"
 
378
 
 
379
        else:
 
380
            if skip_stub:
 
381
                out =  ('    <td><img alt=" " src="%s" style="width: %dpx; ' +
 
382
                        ' height: %dpx; border-width: 0px;"></td>') % \
 
383
                        (src, width, height)
 
384
            else:
 
385
                out = ('    <td><a href="#"><img alt=" " src="%s" ' +
 
386
                      ' style="width: %dpx; height: %dpx; border-width: 0px;">' +
 
387
                      '</a></td>') %  (src, width, height)
 
388
        self.write(out)
 
389
    def parse_urls (self):
 
390
        """
 
391
           This will parse any url targets in the href="XX" fields
 
392
           of the given file and return then as a list
 
393
        """
 
394
        import re
 
395
        url_list = [] 
 
396
        try:
 
397
            html_file = open (self.filename)
 
398
            
 
399
            #Regular expression to  pick everything up to the next doublequote
 
400
            #character after finding  the sequence 'href="'. The found sequences
 
401
            #will be returned as  a list by the "findall" method.
 
402
            expr = re.compile (r"""href\=\"([^\"]*?)\"""")
 
403
            url_list = expr.findall (html_file.read (2 ** 18))
 
404
            html_file.close()
 
405
            
 
406
        except:
 
407
            #silently ignore any errors parsing this. The file being
 
408
            #ovewriten  may not be a  file genrated by py-slice.
 
409
            pass
 
410
            
 
411
        return url_list
 
412
        
210
413
 
211
414
register(
212
 
    "py_slice",
213
 
    "Guillotine implemented ala python, with html output (based on perlotine by Seth Burgess)",
214
 
    "Add guides to an image. Then run this. It will cut along the guides, and give you the html to reassemble the resulting images.",
 
415
    "python-fu-slice",
 
416
    N_("Cuts an image along its guides, creates images and a HTML table snippet"),
 
417
    """Add guides to an image. Then run this. It will cut along the guides,
 
418
    and give you the html to reassemble the resulting images. If you
 
419
    choose to generate javascript for onmouseover and clicked events, it
 
420
    will use the lower three visible layers on the image for normal,
 
421
    onmouseover and clicked states, in that order. If skip caps is
 
422
    enabled, table cells on the edge of the table won't become animated,
 
423
    and its images will be taken from the active layer.""",
215
424
    "Manish Singh",
216
425
    "Manish Singh",
217
426
    "2003",
218
 
    "<Image>/Filters/Web/Py-Slice...",
 
427
    _("_Slice..."),
219
428
    "*",
220
429
    [
221
 
        (PF_STRING, "save_path", "The path to export the HTML to", os.getcwd()),
222
 
        (PF_STRING, "html_filename", "Filename to export", "py-slice.html"),
223
 
        (PF_STRING, "image_basename", "What to call the images", "pyslice"),
224
 
        (PF_RADIO, "image_extension", "The format of the images: {gif, jpg, png}", "gif", (("gif", "gif"), ("jpg", "jpg"), ("png", "png"))),
225
 
        (PF_TOGGLE, "separate_image_dir", "Use a separate directory for images?", FALSE),
226
 
        (PF_STRING, "relative_image_path", "The path to export the images to, relative to the Save Path", "images/"),
227
 
        (PF_TOGGLE, "capitalize_tags", "Capitalize HTML tags?", FALSE),
228
 
        (PF_SPINNER, "cellspacing", "Add space between the table elements", 0, (0,15,1))
 
430
        (PF_DIRNAME, "save-path",     _("Path for HTML export"), os.getcwd()),
 
431
        (PF_STRING, "html-filename",  _("Filename for export"),  "slice.html"),
 
432
        (PF_STRING, "image-basename", _("Image name prefix"),    "slice"),
 
433
        (PF_RADIO, "image-extension", _("Image format"),         "gif", (("gif", "gif"), ("jpg", "jpg"), ("png", "png"))),
 
434
        (PF_TOGGLE, "separate-image-dir",  _("Separate image folder"),
 
435
         False),
 
436
        (PF_STRING, "relative-image-path", _("Folder for image export"), "images"),
 
437
        (PF_SPINNER, "cellspacing", _("Space between table elements"), 0,
 
438
        (0,15,1)),
 
439
        (PF_TOGGLE, "animate",      _("Javascript for onmouseover and clicked"),
 
440
         False),
 
441
        (PF_TOGGLE, "skip-caps",    _("Skip animation for table caps"), True)
229
442
    ],
230
443
    [],
231
 
    pyslice)
 
444
    pyslice,
 
445
    menu="<Image>/Filters/Web",
 
446
    domain=("gimp20-python", gimp.locale_directory)
 
447
    )
232
448
 
233
449
main()