Browse Source

add PIL library

damien 11 years ago
parent
commit
c11b541b2f
5 changed files with 861 additions and 0 deletions
  1. 96 0
      tg2env/bin/pilconvert.py
  2. 524 0
      tg2env/bin/pildriver.py
  3. 94 0
      tg2env/bin/pilfile.py
  4. 54 0
      tg2env/bin/pilfont.py
  5. 93 0
      tg2env/bin/pilprint.py

+ 96 - 0
tg2env/bin/pilconvert.py View File

@@ -0,0 +1,96 @@
1
+#!/home/daccorsi/sources/protos/pboard/tg2env/bin/python
2
+#
3
+# The Python Imaging Library.
4
+# $Id$
5
+#
6
+# convert image files
7
+#
8
+# History:
9
+# 0.1   96-04-20 fl     Created
10
+# 0.2   96-10-04 fl     Use draft mode when converting images
11
+# 0.3   96-12-30 fl     Optimize output (PNG, JPEG)
12
+# 0.4   97-01-18 fl     Made optimize an option (PNG, JPEG)
13
+# 0.5   98-12-30 fl     Fixed -f option (from Anthony Baxter)
14
+#
15
+
16
+import site
17
+import getopt, string, sys
18
+
19
+from PIL import Image
20
+
21
+def usage():
22
+    print "PIL Convert 0.5/1998-12-30 -- convert image files"
23
+    print "Usage: pilconvert [option] infile outfile"
24
+    print
25
+    print "Options:"
26
+    print
27
+    print "  -c <format>  convert to format (default is given by extension)"
28
+    print
29
+    print "  -g           convert to greyscale"
30
+    print "  -p           convert to palette image (using standard palette)"
31
+    print "  -r           convert to rgb"
32
+    print
33
+    print "  -o           optimize output (trade speed for size)"
34
+    print "  -q <value>   set compression quality (0-100, JPEG only)"
35
+    print
36
+    print "  -f           list supported file formats"
37
+    sys.exit(1)
38
+
39
+if len(sys.argv) == 1:
40
+    usage()
41
+
42
+try:
43
+    opt, argv = getopt.getopt(sys.argv[1:], "c:dfgopq:r")
44
+except getopt.error, v:
45
+    print v
46
+    sys.exit(1)
47
+
48
+format = None
49
+convert = None
50
+
51
+options = { }
52
+
53
+for o, a in opt:
54
+
55
+    if o == "-f":
56
+        Image.init()
57
+        id = Image.ID[:]
58
+        id.sort()
59
+        print "Supported formats (* indicates output format):"
60
+        for i in id:
61
+            if Image.SAVE.has_key(i):
62
+                print i+"*",
63
+            else:
64
+                print i,
65
+        sys.exit(1)
66
+
67
+    elif o == "-c":
68
+        format = a
69
+
70
+    if o == "-g":
71
+        convert = "L"
72
+    elif o == "-p":
73
+        convert = "P"
74
+    elif o == "-r":
75
+        convert = "RGB"
76
+
77
+    elif o == "-o":
78
+        options["optimize"] = 1
79
+    elif o == "-q":
80
+        options["quality"] = string.atoi(a)
81
+
82
+if len(argv) != 2:
83
+    usage()
84
+
85
+try:
86
+    im = Image.open(argv[0])
87
+    if convert and im.mode != convert:
88
+        im.draft(convert, im.size)
89
+        im = im.convert(convert)
90
+    if format:
91
+        apply(im.save, (argv[1], format), options)
92
+    else:
93
+        apply(im.save, (argv[1],), options)
94
+except:
95
+    print "cannot convert image",
96
+    print "(%s:%s)" % (sys.exc_type, sys.exc_value)

+ 524 - 0
tg2env/bin/pildriver.py View File

@@ -0,0 +1,524 @@
1
+#!/home/daccorsi/sources/protos/pboard/tg2env/bin/python
2
+"""PILdriver, an image-processing calculator using PIL.
3
+
4
+An instance of class PILDriver is essentially a software stack machine
5
+(Polish-notation interpreter) for sequencing PIL image
6
+transformations.  The state of the instance is the interpreter stack.
7
+
8
+The only method one will normally invoke after initialization is the
9
+`execute' method.  This takes an argument list of tokens, pushes them
10
+onto the instance's stack, and then tries to clear the stack by
11
+successive evaluation of PILdriver operators.  Any part of the stack
12
+not cleaned off persists and is part of the evaluation context for
13
+the next call of the execute method.
14
+
15
+PILDriver doesn't catch any exceptions, on the theory that these
16
+are actually diagnostic information that should be interpreted by
17
+the calling code.
18
+
19
+When called as a script, the command-line arguments are passed to
20
+a PILDriver instance.  If there are no command-line arguments, the
21
+module runs an interactive interpreter, each line of which is split into
22
+space-separated tokens and passed to the execute method.
23
+
24
+In the method descriptions below, a first line beginning with the string
25
+`usage:' means this method can be invoked with the token that follows
26
+it.  Following <>-enclosed arguments describe how the method interprets
27
+the entries on the stack.  Each argument specification begins with a
28
+type specification: either `int', `float', `string', or `image'.
29
+
30
+All operations consume their arguments off the stack (use `dup' to
31
+keep copies around).  Use `verbose 1' to see the stack state displayed
32
+before each operation.
33
+
34
+Usage examples:
35
+
36
+    `show crop 0 0 200 300 open test.png' loads test.png, crops out a portion
37
+of its upper-left-hand corner and displays the cropped portion.
38
+
39
+    `save rotated.png rotate 30 open test.tiff' loads test.tiff, rotates it
40
+30 degrees, and saves the result as rotated.png (in PNG format).
41
+"""
42
+# by Eric S. Raymond <esr@thyrsus.com>
43
+# $Id$
44
+
45
+# TO DO:
46
+# 1. Add PILFont capabilities, once that's documented.
47
+# 2. Add PILDraw operations.
48
+# 3. Add support for composing and decomposing multiple-image files.
49
+#
50
+
51
+from PIL import Image
52
+import string
53
+
54
+class PILDriver:
55
+
56
+    verbose = 0
57
+
58
+    def do_verbose(self):
59
+        """usage: verbose <int:num>
60
+
61
+        Set verbosity flag from top of stack.
62
+        """
63
+        self.verbose = self.do_pop()
64
+
65
+    # The evaluation stack (internal only)
66
+
67
+    stack = []          # Stack of pending operations
68
+
69
+    def push(self, item):
70
+        "Push an argument onto the evaluation stack."
71
+        self.stack = [item] + self.stack
72
+
73
+    def top(self):
74
+        "Return the top-of-stack element."
75
+        return self.stack[0]
76
+
77
+    # Stack manipulation (callable)
78
+
79
+    def do_clear(self):
80
+        """usage: clear
81
+
82
+        Clear the stack.
83
+        """
84
+        self.stack = []
85
+
86
+    def do_pop(self):
87
+        """usage: pop
88
+
89
+        Discard the top element on the stack.
90
+        """
91
+        top = self.stack[0]
92
+        self.stack = self.stack[1:]
93
+        return top
94
+
95
+    def do_dup(self):
96
+        """usage: dup
97
+
98
+        Duplicate the top-of-stack item.
99
+        """
100
+        if hasattr(self, 'format'):     # If it's an image, do a real copy
101
+            dup = self.stack[0].copy()
102
+        else:
103
+            dup = self.stack[0]
104
+        self.stack = [dup] + self.stack
105
+
106
+    def do_swap(self):
107
+        """usage: swap
108
+
109
+        Swap the top-of-stack item with the next one down.
110
+        """
111
+        self.stack = [self.stack[1], self.stack[0]] + self.stack[2:]
112
+
113
+    # Image module functions (callable)
114
+
115
+    def do_new(self):
116
+        """usage: new <int:xsize> <int:ysize> <int:color>:
117
+
118
+        Create and push a greyscale image of given size and color.
119
+        """
120
+        xsize = int(self.do_pop())
121
+        ysize = int(self.do_pop())
122
+        color = int(self.do_pop())
123
+        self.push(Image.new("L", (xsize, ysize), color))
124
+
125
+    def do_open(self):
126
+        """usage: open <string:filename>
127
+
128
+        Open the indicated image, read it, push the image on the stack.
129
+        """
130
+        self.push(Image.open(self.do_pop()))
131
+
132
+    def do_blend(self):
133
+        """usage: blend <image:pic1> <image:pic2> <float:alpha>
134
+
135
+        Replace two images and an alpha with the blended image.
136
+        """
137
+        image1 = self.do_pop()
138
+        image2 = self.do_pop()
139
+        alpha = float(self.do_pop())
140
+        self.push(Image.blend(image1, image2, alpha))
141
+
142
+    def do_composite(self):
143
+        """usage: composite <image:pic1> <image:pic2> <image:mask>
144
+
145
+        Replace two images and a mask with their composite.
146
+        """
147
+        image1 = self.do_pop()
148
+        image2 = self.do_pop()
149
+        mask = self.do_pop()
150
+        self.push(Image.composite(image1, image2, mask))
151
+
152
+    def do_merge(self):
153
+        """usage: merge <string:mode> <image:pic1> [<image:pic2> [<image:pic3> [<image:pic4>]]]
154
+
155
+        Merge top-of stack images in a way described by the mode.
156
+        """
157
+        mode = self.do_pop()
158
+        bandlist = []
159
+        for band in mode:
160
+            bandlist.append(self.do_pop())
161
+        self.push(Image.merge(mode, bandlist))
162
+
163
+    # Image class methods
164
+
165
+    def do_convert(self):
166
+        """usage: convert <string:mode> <image:pic1>
167
+
168
+        Convert the top image to the given mode.
169
+        """
170
+        mode = self.do_pop()
171
+        image = self.do_pop()
172
+        self.push(image.convert(mode))
173
+
174
+    def do_copy(self):
175
+        """usage: copy <image:pic1>
176
+
177
+        Make and push a true copy of the top image.
178
+        """
179
+        self.dup()
180
+
181
+    def do_crop(self):
182
+        """usage: crop <int:left> <int:upper> <int:right> <int:lower> <image:pic1>
183
+
184
+        Crop and push a rectangular region from the current image.
185
+        """
186
+        left = int(self.do_pop())
187
+        upper = int(self.do_pop())
188
+        right = int(self.do_pop())
189
+        lower = int(self.do_pop())
190
+        image = self.do_pop()
191
+        self.push(image.crop((left, upper, right, lower)))
192
+
193
+    def do_draft(self):
194
+        """usage: draft <string:mode> <int:xsize> <int:ysize>
195
+
196
+        Configure the loader for a given mode and size.
197
+        """
198
+        mode = self.do_pop()
199
+        xsize = int(self.do_pop())
200
+        ysize = int(self.do_pop())
201
+        self.push(self.draft(mode, (xsize, ysize)))
202
+
203
+    def do_filter(self):
204
+        """usage: filter <string:filtername> <image:pic1>
205
+
206
+        Process the top image with the given filter.
207
+        """
208
+        import ImageFilter
209
+        filter = eval("ImageFilter." + string.upper(self.do_pop()))
210
+        image = self.do_pop()
211
+        self.push(image.filter(filter))
212
+
213
+    def do_getbbox(self):
214
+        """usage: getbbox
215
+
216
+        Push left, upper, right, and lower pixel coordinates of the top image.
217
+        """
218
+        bounding_box = self.do_pop().getbbox()
219
+        self.push(bounding_box[3])
220
+        self.push(bounding_box[2])
221
+        self.push(bounding_box[1])
222
+        self.push(bounding_box[0])
223
+
224
+    def do_getextrema(self):
225
+        """usage: extrema
226
+
227
+        Push minimum and maximum pixel values of the top image.
228
+        """
229
+        extrema = self.do_pop().extrema()
230
+        self.push(extrema[1])
231
+        self.push(extrema[0])
232
+
233
+    def do_offset(self):
234
+        """usage: offset <int:xoffset> <int:yoffset> <image:pic1>
235
+
236
+        Offset the pixels in the top image.
237
+        """
238
+        xoff = int(self.do_pop())
239
+        yoff = int(self.do_pop())
240
+        image = self.do_pop()
241
+        self.push(image.offset(xoff, yoff))
242
+
243
+    def do_paste(self):
244
+        """usage: paste <image:figure> <int:xoffset> <int:yoffset> <image:ground>
245
+
246
+        Paste figure image into ground with upper left at given offsets.
247
+        """
248
+        figure = self.do_pop()
249
+        xoff = int(self.do_pop())
250
+        yoff = int(self.do_pop())
251
+        ground = self.do_pop()
252
+        if figure.mode == "RGBA":
253
+            ground.paste(figure, (xoff, yoff), figure)
254
+        else:
255
+            ground.paste(figure, (xoff, yoff))
256
+        self.push(ground)
257
+
258
+    def do_resize(self):
259
+        """usage: resize <int:xsize> <int:ysize> <image:pic1>
260
+
261
+        Resize the top image.
262
+        """
263
+        ysize = int(self.do_pop())
264
+        xsize = int(self.do_pop())
265
+        image = self.do_pop()
266
+        self.push(image.resize((xsize, ysize)))
267
+
268
+    def do_rotate(self):
269
+        """usage: rotate <int:angle> <image:pic1>
270
+
271
+        Rotate image through a given angle
272
+        """
273
+        angle = int(self.do_pop())
274
+        image = self.do_pop()
275
+        self.push(image.rotate(angle))
276
+
277
+    def do_save(self):
278
+        """usage: save <string:filename> <image:pic1>
279
+
280
+        Save image with default options.
281
+        """
282
+        filename = self.do_pop()
283
+        image = self.do_pop()
284
+        image.save(filename)
285
+
286
+    def do_save2(self):
287
+        """usage: save2 <string:filename> <string:options> <image:pic1>
288
+
289
+        Save image with specified options.
290
+        """
291
+        filename = self.do_pop()
292
+        options = self.do_pop()
293
+        image = self.do_pop()
294
+        image.save(filename, None, options)
295
+
296
+    def do_show(self):
297
+        """usage: show <image:pic1>
298
+
299
+        Display and pop the top image.
300
+        """
301
+        self.do_pop().show()
302
+
303
+    def do_thumbnail(self):
304
+        """usage: thumbnail <int:xsize> <int:ysize> <image:pic1>
305
+
306
+        Modify the top image in the stack to contain a thumbnail of itself.
307
+        """
308
+        ysize = int(self.do_pop())
309
+        xsize = int(self.do_pop())
310
+        self.top().thumbnail((xsize, ysize))
311
+
312
+    def do_transpose(self):
313
+        """usage: transpose <string:operator> <image:pic1>
314
+
315
+        Transpose the top image.
316
+        """
317
+        transpose = string.upper(self.do_pop())
318
+        image = self.do_pop()
319
+        self.push(image.transpose(transpose))
320
+
321
+    # Image attributes
322
+
323
+    def do_format(self):
324
+        """usage: format <image:pic1>
325
+
326
+        Push the format of the top image onto the stack.
327
+        """
328
+        self.push(self.pop().format)
329
+
330
+    def do_mode(self):
331
+        """usage: mode <image:pic1>
332
+
333
+        Push the mode of the top image onto the stack.
334
+        """
335
+        self.push(self.pop().mode)
336
+
337
+    def do_size(self):
338
+        """usage: size <image:pic1>
339
+
340
+        Push the image size on the stack as (y, x).
341
+        """
342
+        size = self.pop().size
343
+        self.push(size[0])
344
+        self.push(size[1])
345
+
346
+    # ImageChops operations
347
+
348
+    def do_invert(self):
349
+        """usage: invert <image:pic1>
350
+
351
+        Invert the top image.
352
+        """
353
+        import ImageChops
354
+        self.push(ImageChops.invert(self.do_pop()))
355
+
356
+    def do_lighter(self):
357
+        """usage: lighter <image:pic1> <image:pic2>
358
+
359
+        Pop the two top images, push an image of the lighter pixels of both.
360
+        """
361
+        import ImageChops
362
+        image1 = self.do_pop()
363
+        image2 = self.do_pop()
364
+        self.push(ImageChops.lighter(image1, image2))
365
+
366
+    def do_darker(self):
367
+        """usage: darker <image:pic1> <image:pic2>
368
+
369
+        Pop the two top images, push an image of the darker pixels of both.
370
+        """
371
+        import ImageChops
372
+        image1 = self.do_pop()
373
+        image2 = self.do_pop()
374
+        self.push(ImageChops.darker(image1, image2))
375
+
376
+    def do_difference(self):
377
+        """usage: difference <image:pic1> <image:pic2>
378
+
379
+        Pop the two top images, push the difference image
380
+        """
381
+        import ImageChops
382
+        image1 = self.do_pop()
383
+        image2 = self.do_pop()
384
+        self.push(ImageChops.difference(image1, image2))
385
+
386
+    def do_multiply(self):
387
+        """usage: multiply <image:pic1> <image:pic2>
388
+
389
+        Pop the two top images, push the multiplication image.
390
+        """
391
+        import ImageChops
392
+        image1 = self.do_pop()
393
+        image2 = self.do_pop()
394
+        self.push(ImageChops.multiply(image1, image2))
395
+
396
+    def do_screen(self):
397
+        """usage: screen <image:pic1> <image:pic2>
398
+
399
+        Pop the two top images, superimpose their inverted versions.
400
+        """
401
+        import ImageChops
402
+        image2 = self.do_pop()
403
+        image1 = self.do_pop()
404
+        self.push(ImageChops.screen(image1, image2))
405
+
406
+    def do_add(self):
407
+        """usage: add <image:pic1> <image:pic2> <int:offset> <float:scale>
408
+
409
+        Pop the two top images, produce the scaled sum with offset.
410
+        """
411
+        import ImageChops
412
+        image1 = self.do_pop()
413
+        image2 = self.do_pop()
414
+        scale = float(self.do_pop())
415
+        offset = int(self.do_pop())
416
+        self.push(ImageChops.add(image1, image2, scale, offset))
417
+
418
+    def do_subtract(self):
419
+        """usage: subtract <image:pic1> <image:pic2> <int:offset> <float:scale>
420
+
421
+        Pop the two top images, produce the scaled difference with offset.
422
+        """
423
+        import ImageChops
424
+        image1 = self.do_pop()
425
+        image2 = self.do_pop()
426
+        scale = float(self.do_pop())
427
+        offset = int(self.do_pop())
428
+        self.push(ImageChops.subtract(image1, image2, scale, offset))
429
+
430
+    # ImageEnhance classes
431
+
432
+    def do_color(self):
433
+        """usage: color <image:pic1>
434
+
435
+        Enhance color in the top image.
436
+        """
437
+        import ImageEnhance
438
+        factor = float(self.do_pop())
439
+        image = self.do_pop()
440
+        enhancer = ImageEnhance.Color(image)
441
+        self.push(enhancer.enhance(factor))
442
+
443
+    def do_contrast(self):
444
+        """usage: contrast <image:pic1>
445
+
446
+        Enhance contrast in the top image.
447
+        """
448
+        import ImageEnhance
449
+        factor = float(self.do_pop())
450
+        image = self.do_pop()
451
+        enhancer = ImageEnhance.Color(image)
452
+        self.push(enhancer.enhance(factor))
453
+
454
+    def do_brightness(self):
455
+        """usage: brightness <image:pic1>
456
+
457
+        Enhance brightness in the top image.
458
+        """
459
+        import ImageEnhance
460
+        factor = float(self.do_pop())
461
+        image = self.do_pop()
462
+        enhancer = ImageEnhance.Color(image)
463
+        self.push(enhancer.enhance(factor))
464
+
465
+    def do_sharpness(self):
466
+        """usage: sharpness <image:pic1>
467
+
468
+        Enhance sharpness in the top image.
469
+        """
470
+        import ImageEnhance
471
+        factor = float(self.do_pop())
472
+        image = self.do_pop()
473
+        enhancer = ImageEnhance.Color(image)
474
+        self.push(enhancer.enhance(factor))
475
+
476
+    # The interpreter loop
477
+
478
+    def execute(self, list):
479
+        "Interpret a list of PILDriver commands."
480
+        list.reverse()
481
+        while len(list) > 0:
482
+            self.push(list[0])
483
+            list = list[1:]
484
+            if self.verbose:
485
+                print "Stack: " + `self.stack`
486
+            top = self.top()
487
+            if type(top) != type(""):
488
+                continue;
489
+            funcname = "do_" + top
490
+            if not hasattr(self, funcname):
491
+                continue
492
+            else:
493
+                self.do_pop()
494
+                func = getattr(self, funcname)
495
+                func()
496
+
497
+if __name__ == '__main__':
498
+    import sys
499
+    try:
500
+        import readline
501
+    except ImportError:
502
+        pass # not available on all platforms
503
+
504
+    # If we see command-line arguments, interpret them as a stack state
505
+    # and execute.  Otherwise go interactive.
506
+
507
+    driver = PILDriver()
508
+    if len(sys.argv[1:]) > 0:
509
+        driver.execute(sys.argv[1:])
510
+    else:
511
+        print "PILDriver says hello."
512
+        while 1:
513
+            try:
514
+                line = raw_input('pildriver> ');
515
+            except EOFError:
516
+                print "\nPILDriver says goodbye."
517
+                break
518
+            driver.execute(string.split(line))
519
+            print driver.stack
520
+
521
+# The following sets edit modes for GNU EMACS
522
+# Local Variables:
523
+# mode:python
524
+# End:

+ 94 - 0
tg2env/bin/pilfile.py View File

@@ -0,0 +1,94 @@
1
+#!/home/daccorsi/sources/protos/pboard/tg2env/bin/python
2
+#
3
+# The Python Imaging Library.
4
+# $Id$
5
+#
6
+# a utility to identify image files
7
+#
8
+# this script identifies image files, extracting size and
9
+# pixel mode information for known file formats.  Note that
10
+# you don't need the PIL C extension to use this module.
11
+#
12
+# History:
13
+# 0.0 1995-09-01 fl   Created
14
+# 0.1 1996-05-18 fl   Modified options, added debugging mode
15
+# 0.2 1996-12-29 fl   Added verify mode
16
+# 0.3 1999-06-05 fl   Don't mess up on class exceptions (1.5.2 and later)
17
+# 0.4 2003-09-30 fl   Expand wildcards on Windows; robustness tweaks
18
+#
19
+
20
+import site
21
+import getopt, glob, sys
22
+
23
+from PIL import Image
24
+
25
+if len(sys.argv) == 1:
26
+    print "PIL File 0.4/2003-09-30 -- identify image files"
27
+    print "Usage: pilfile [option] files..."
28
+    print "Options:"
29
+    print "  -f  list supported file formats"
30
+    print "  -i  show associated info and tile data"
31
+    print "  -v  verify file headers"
32
+    print "  -q  quiet, don't warn for unidentified/missing/broken files"
33
+    sys.exit(1)
34
+
35
+try:
36
+    opt, args = getopt.getopt(sys.argv[1:], "fqivD")
37
+except getopt.error, v:
38
+    print v
39
+    sys.exit(1)
40
+
41
+verbose = quiet = verify = 0
42
+
43
+for o, a in opt:
44
+    if o == "-f":
45
+        Image.init()
46
+        id = Image.ID[:]
47
+        id.sort()
48
+        print "Supported formats:"
49
+        for i in id:
50
+            print i,
51
+        sys.exit(1)
52
+    elif o == "-i":
53
+        verbose = 1
54
+    elif o == "-q":
55
+        quiet = 1
56
+    elif o == "-v":
57
+        verify = 1
58
+    elif o == "-D":
59
+        Image.DEBUG = Image.DEBUG + 1
60
+
61
+def globfix(files):
62
+    # expand wildcards where necessary
63
+    if sys.platform == "win32":
64
+        out = []
65
+        for file in files:
66
+            if glob.has_magic(file):
67
+                out.extend(glob.glob(file))
68
+            else:
69
+                out.append(file)
70
+        return out
71
+    return files
72
+
73
+for file in globfix(args):
74
+    try:
75
+        im = Image.open(file)
76
+        print "%s:" % file, im.format, "%dx%d" % im.size, im.mode,
77
+        if verbose:
78
+            print im.info, im.tile,
79
+        print
80
+        if verify:
81
+            try:
82
+                im.verify()
83
+            except:
84
+                if not quiet:
85
+                    print "failed to verify image",
86
+                    print "(%s:%s)" % (sys.exc_type, sys.exc_value)
87
+    except IOError, v:
88
+        if not quiet:
89
+            print file, "failed:", v
90
+    except:
91
+        import traceback
92
+        if not quiet:
93
+            print file, "failed:", "unexpected error"
94
+            traceback.print_exc(file=sys.stdout)

+ 54 - 0
tg2env/bin/pilfont.py View File

@@ -0,0 +1,54 @@
1
+#
2
+# The Python Imaging Library
3
+# $Id$
4
+#
5
+# PIL raster font compiler
6
+#
7
+# history:
8
+# 1997-08-25 fl   created
9
+# 2002-03-10 fl   use "from PIL import"
10
+#
11
+
12
+VERSION = "0.4"
13
+
14
+import site
15
+import glob, os, sys
16
+
17
+# drivers
18
+from PIL import BdfFontFile
19
+from PIL import PcfFontFile
20
+
21
+if len(sys.argv) <= 1:
22
+    print "PILFONT", VERSION, "-- PIL font compiler."
23
+    print
24
+    print "Usage: pilfont fontfiles..."
25
+    print
26
+    print "Convert given font files to the PIL raster font format."
27
+    print "This version of pilfont supports X BDF and PCF fonts."
28
+    sys.exit(1)
29
+
30
+files = []
31
+for f in sys.argv[1:]:
32
+    files = files + glob.glob(f)
33
+
34
+for f in files:
35
+
36
+    print f + "...",
37
+
38
+    try:
39
+
40
+        fp = open(f, "rb")
41
+
42
+        try:
43
+            p = PcfFontFile.PcfFontFile(fp)
44
+        except SyntaxError:
45
+            fp.seek(0)
46
+            p = BdfFontFile.BdfFontFile(fp)
47
+
48
+        p.save(f)
49
+
50
+    except (SyntaxError, IOError):
51
+        print "failed"
52
+
53
+    else:
54
+        print "OK"

+ 93 - 0
tg2env/bin/pilprint.py View File

@@ -0,0 +1,93 @@
1
+#!/home/daccorsi/sources/protos/pboard/tg2env/bin/python
2
+#
3
+# The Python Imaging Library.
4
+# $Id$
5
+#
6
+# print image files to postscript printer
7
+#
8
+# History:
9
+# 0.1   1996-04-20 fl   Created
10
+# 0.2   1996-10-04 fl   Use draft mode when converting.
11
+# 0.3   2003-05-06 fl   Fixed a typo or two.
12
+#
13
+
14
+VERSION = "pilprint 0.3/2003-05-05"
15
+
16
+from PIL import Image
17
+from PIL import PSDraw
18
+
19
+letter = ( 1.0*72, 1.0*72, 7.5*72, 10.0*72 )
20
+
21
+def description(file, image):
22
+    import os
23
+    title = os.path.splitext(os.path.split(file)[1])[0]
24
+    format = " (%dx%d "
25
+    if image.format:
26
+        format = " (" + image.format + " %dx%d "
27
+    return title + format % image.size + image.mode + ")"
28
+
29
+import getopt, os, sys
30
+
31
+if len(sys.argv) == 1:
32
+    print "PIL Print 0.2a1/96-10-04 -- print image files"
33
+    print "Usage: pilprint files..."
34
+    print "Options:"
35
+    print "  -c            colour printer (default is monochrome)"
36
+    print "  -p            print via lpr (default is stdout)"
37
+    print "  -P <printer>  same as -p but use given printer"
38
+    sys.exit(1)
39
+
40
+try:
41
+    opt, argv = getopt.getopt(sys.argv[1:], "cdpP:")
42
+except getopt.error, v:
43
+    print v
44
+    sys.exit(1)
45
+
46
+printer = None # print to stdout
47
+monochrome = 1 # reduce file size for most common case
48
+
49
+for o, a in opt:
50
+    if o == "-d":
51
+        # debug: show available drivers
52
+        Image.init()
53
+        print Image.ID
54
+        sys.exit(1)
55
+    elif o == "-c":
56
+        # colour printer
57
+        monochrome = 0
58
+    elif o == "-p":
59
+        # default printer channel
60
+        printer = "lpr"
61
+    elif o == "-P":
62
+        # printer channel
63
+        printer = "lpr -P%s" % a
64
+
65
+for file in argv:
66
+    try:
67
+
68
+        im = Image.open(file)
69
+
70
+        title = description(file, im)
71
+
72
+        if monochrome and im.mode not in ["1", "L"]:
73
+            im.draft("L", im.size)
74
+            im = im.convert("L")
75
+
76
+        if printer:
77
+            fp = os.popen(printer, "w")
78
+        else:
79
+            fp = sys.stdout
80
+
81
+        ps = PSDraw.PSDraw(fp)
82
+
83
+        ps.begin_document()
84
+        ps.setfont("Helvetica-Narrow-Bold", 18)
85
+        ps.text((letter[0], letter[3]+24), title)
86
+        ps.setfont("Helvetica-Narrow-Bold", 8)
87
+        ps.text((letter[0], letter[1]-30), VERSION)
88
+        ps.image(letter, im)
89
+        ps.end_document()
90
+
91
+    except:
92
+        print "cannot print image",
93
+        print "(%s:%s)" % (sys.exc_type, sys.exc_value)