1 | # ---------------------------------------------------------------------- |
---|
2 | # EXAMPLE: Rappture <dequence> elements |
---|
3 | # ====================================================================== |
---|
4 | # AUTHOR: Martin Hunt, Purdue University |
---|
5 | # Copyright (c) 2015 HUBzero Foundation, LLC |
---|
6 | # |
---|
7 | # See the file "license.terms" for information on usage and |
---|
8 | # redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
9 | # ====================================================================== |
---|
10 | |
---|
11 | import Rappture |
---|
12 | import sys |
---|
13 | from PIL import Image |
---|
14 | from io import BytesIO |
---|
15 | from Rappture import RPENC_B64, RPENC_ZB64 |
---|
16 | from Rappture.encoding import decode, encode |
---|
17 | |
---|
18 | # uncomment these for debugging |
---|
19 | # sys.stdout = open('seq.out', 'w') |
---|
20 | # sys.stderr = open('seq.err', 'w') |
---|
21 | |
---|
22 | |
---|
23 | # rotate image data |
---|
24 | def rotate_image(data, angle): |
---|
25 | |
---|
26 | # bug workaround in some PIL versions |
---|
27 | def fileno(): |
---|
28 | raise AttributeError |
---|
29 | |
---|
30 | # open image from data and rotate |
---|
31 | image = Image.open(BytesIO(data)) |
---|
32 | rot = image.rotate(angle, expand=True) |
---|
33 | # save image to a file in memory |
---|
34 | memfile = BytesIO() |
---|
35 | memfile.fileno = fileno # required in some broken PILs |
---|
36 | rot.save(memfile, image.format) |
---|
37 | return memfile.getvalue() |
---|
38 | |
---|
39 | |
---|
40 | # open the XML file containing the run parameters |
---|
41 | rx = Rappture.PyXml(sys.argv[1]) |
---|
42 | |
---|
43 | data = rx['input.image.current'].value |
---|
44 | # image data in B64 encoded in the xml |
---|
45 | data = decode(data, RPENC_B64) |
---|
46 | |
---|
47 | nframes = int(rx['input.integer(nframes).current'].value) |
---|
48 | |
---|
49 | image = Image.open(BytesIO(data)) |
---|
50 | |
---|
51 | outs = rx['output.sequence(outs)'] |
---|
52 | outs['about.label'] = 'Animated Sequence' |
---|
53 | outs['index.label'] = 'Frame' |
---|
54 | |
---|
55 | for i in range(nframes): |
---|
56 | element = outs['element(%s)' % i] |
---|
57 | element['index'] = i |
---|
58 | element['about.label'] = 'Frame %s' % i |
---|
59 | rdata = rotate_image(data, i*360.0/nframes) |
---|
60 | |
---|
61 | # Image data must be B64 or ZB64 encoded. |
---|
62 | # The next two lines are equivalent. Can use RPENC_B64 or RPENC_ZB64 |
---|
63 | element['image.current'] = encode(rdata, RPENC_ZB64) |
---|
64 | # element.put('image.current', rdata, compress=True) |
---|
65 | |
---|
66 | # save the updated XML describing the run... |
---|
67 | rx.close() |
---|