annotate data/plugin/macro/MoinImage.py @ 263:448a086d840c

MoinImage: simplify API
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 13 Sep 2008 20:21:20 +0200
parents c605998e1123
children b7e7be4340b0
rev   line source
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
1 # -*- coding: iso-8859-1 -*-
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
2 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
3 MoinMoin - MoinImage image rendering support class and a test macro using it.
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
4
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
5 Features:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
6 * rendering (and caching) of thumbnails/webnails/originals
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
7 * gives ready-to-use image urls
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
8 * auto-rotation based on EXIF information
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
9 * determines creation time from EXIF or file system
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
10 * easy access to some EXIF data (cached)
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
11
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
12 Requires PIL and ExifTags libs.
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
13
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
14 @copyright: 2008 MoinMoin:ThomasWaldmann,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
15 2008 MoinMoin:ReimarBauer
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
16 @license: GNU GPL, see COPYING for details.
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
17 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
18
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
19 import os, time
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
20 import StringIO
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
21
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
22 from MoinMoin import caching, wikiutil
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
23 from MoinMoin.action import AttachFile, cache
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
24
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
25 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
26 import Image
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
27 except ImportError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
28 Image = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
29
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
30 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
31 import ExifTags
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
32 except ImportError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
33 ExifTags = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
34
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
35 class MoinImage(object):
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
36 # predefined sizes (width, height) - use them if you like:
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
37 WEBNAIL_SIZE = (640, 480)
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
38 THUMBNAIL_SIZE = (128, 128)
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
39
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
40 # we don't process and cache all EXIF infos, but just these:
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
41 EXIF_CACHED = set(['DateTimeOriginal', 'TimeZoneOffset', 'Orientation', ])
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
42
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
43 def __init__(self, request,
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
44 item_name, # PageName/AttachName for now, later this is just the item name
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
45 description=u'', # we just store this, but we do not use it in MoinImage
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
46 ):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
47 self.request = request
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
48 self.pagename, self.attachname = item_name.rsplit('/', 1)
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
49 self.description = description
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
50
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
51 # cached property values:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
52 self.__filename = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
53 self.__content_type = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
54 self.__cache_key = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
55 self.__image = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
56 self.__exif = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
57 self.__ctime = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
58
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
59 def _get_filename(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
60 if self.__filename is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
61 self.__filename = AttachFile.getFilename(self.request, self.pagename, self.attachname)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
62 return self.__filename
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
63 _filename = property(_get_filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
64
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
65 def _get_content_type(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
66 if self.__content_type is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
67 self.__content_type = wikiutil.MimeType(filename=self._filename).mime_type()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
68 return self.__content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
69 content_type = property(_get_content_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
70
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
71 def _get_image(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
72 if self.__image is None and Image is not None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
73 self.__image = Image.open(self._filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
74 return self.__image
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
75 image = property(_get_image) # the original image (PIL Image object) or None
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
76
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
77 def _get_cache_key(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
78 if self.__cache_key is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
79 self.__cache_key = cache.key(self.request, itemname=self.pagename, attachname=self.attachname)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
80 return self.__cache_key
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
81 _cache_key = property(_get_cache_key)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
82
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
83 def _get_exif_data(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
84 """ return exif data for this image, use a cache for them """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
85 if self.__exif is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
86 key = self._cache_key
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
87 exif_cache = caching.CacheEntry(self.request, 'exif', key, 'wiki',
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
88 use_pickle=True, do_locking=False)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
89 if not exif_cache.exists():
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
90 # we don't want to cache all EXIF data, just a few interesting values
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
91 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
92 exif_data = {}
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
93 if self.image is not None: # we have PIL
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
94 for tag, value in self.image._getexif().items():
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
95 tag_name = ExifTags.TAGS.get(tag)
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
96 if tag_name in self.EXIF_CACHED:
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
97 exif_data[tag_name] = value
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
98 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
99 time_str = exif_data['DateTimeOriginal']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
100 tm = time.strptime(time_str, "%Y:%m:%d %H:%M:%S")
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
101 t = time.mktime(tm)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
102 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
103 tz_str = exif_data['TimeZoneOffset']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
104 tz_offset = int(tz_str) * 3600
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
105 except:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
106 tz_offset = 0
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
107 # mktime is inverse function of (our) localtime, adjust by time.timezone
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
108 t -= time.timezone + tz_offset
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
109 except:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
110 t = 0
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
111 exif_data['DateTimeOriginal'] = t
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
112 except (IOError, AttributeError):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
113 exif_data = {}
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
114 exif_cache.update(exif_data)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
115 self.__exif = exif_data
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
116 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
117 self.__exif = exif_cache.content()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
118 return self.__exif
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
119 exif = property(_get_exif_data) # dict of preprocessed EXIF data (string -> value)
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
120
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
121 def _get_ctime(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
122 """ return creation time of image (either from EXIF or file date) as UNIX timestamp """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
123 if self.__ctime is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
124 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
125 ctime = self.exif['DateTimeOriginal']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
126 except KeyError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
127 ctime = os.path.getctime(self._filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
128 self.__ctime = ctime
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
129 return self.__ctime
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
130 ctime = property(_get_ctime)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
131
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
132 def _transform(self, size=None, content_type=None, transpose_op=None):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
133 """ resize to new size (optional), transpose according to exif infos,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
134 return data as content_type (default: same ct as original image)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
135 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
136 if content_type is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
137 content_type = self.content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
138 if content_type == 'image/jpeg':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
139 output_type = 'JPEG'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
140 elif content_type == 'image/png':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
141 output_type = 'PNG'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
142 elif content_type == 'image/gif':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
143 output_type = 'GIF'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
144 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
145 raise ValueError("content_type %r not supported" % content_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
146 image = self.image
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
147 if image is not None: # we have PIL
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
148 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
149 # if we have EXIF data, we can transpose (e.g. rotate left),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
150 # so the rendered image is correctly oriented:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
151 transpose_op = transpose_op or self.exif['Orientation']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
152 except KeyError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
153 transpose_op = 1 # no change
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
154
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
155 if size is not None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
156 image = image.copy() # create copy first as thumbnail works in-place
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
157 image.thumbnail(size, Image.ANTIALIAS)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
158
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
159 transpose_func = {
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
160 1: lambda image: image,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
161 2: lambda image: image.transpose(Image.FLIP_LEFT_RIGHT),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
162 3: lambda image: image.transpose(Image.ROTATE_180),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
163 4: lambda image: image.transpose(Image.FLIP_TOP_BOTTOM),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
164 5: lambda image: image.transpose(Image.ROTATE_90).transpose(Image.FLIP_TOP_BOTTOM),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
165 6: lambda image: image.transpose(Image.ROTATE_270),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
166 7: lambda image: image.transpose(Image.ROTATE_90).transpose(Image.FLIP_LEFT_RIGHT),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
167 8: lambda image: image.transpose(Image.ROTATE_90),
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
168 }
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
169 image = transpose_func[transpose_op](image)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
170
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
171 buf = StringIO.StringIO()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
172 image.save(buf, output_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
173 buf.flush() # XXX needed?
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
174 data = buf.getvalue()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
175 buf.close()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
176 else: # XXX what to do without PIL?
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
177 data = ''
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
178 return content_type, data
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
179
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
180 def url(self, size=None):
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
181 """ return a cache url for a rendering of this image with specified size -
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
182 the code automatically makes sure that the cache contains that rendering.
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
183 If size is None, it gives a url for the full image size rendering.
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
184 Otherwise, size has to be a tuple (w, h) - if you like, you can use
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
185 these class level constant sizes:
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
186 WEBNAIL_SIZE - medium size, one of those likely to fit in a browser window
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
187 THUMBNAIL_SIZE - small size, for showing collections
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
188 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
189 request = self.request
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
190 content_type = self.content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
191 if size is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
192 size_str = 'orig'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
193 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
194 size_str = '%d_%d' % size
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
195 key = '%s_%s_%s' % (content_type.replace('/', '_'), size_str, self._cache_key)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
196 if not cache.exists(request, key):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
197 content_type, data = self._transform(size=size, content_type=content_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
198 cache.put(request, key, data, content_type=content_type)
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
199 return cache.url(request, key)
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
200
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
201
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
202 def macro_MoinImage(macro, itemname=wikiutil.required_arg(unicode), desc=u''):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
203 """ Embed an Image into a wiki page -
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
204 currently more for testing MoinImage class than for practical use:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
205
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
206 <<MoinImage(PageName/attachname,sample image)>>
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
207 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
208 request = macro.request
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
209 fmt = macro.formatter
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
210 thispagename = fmt.page.page_name
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
211 pagename, fname = AttachFile.absoluteName(itemname, thispagename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
212 img = MoinImage(request, itemname, desc)
263
448a086d840c MoinImage: simplify API
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents: 262
diff changeset
213 return (fmt.image(src=img.url(img.THUMBNAIL_SIZE), alt=img.description) +
262
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
214 fmt.text(time.asctime(time.gmtime(img.ctime))) +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
215 ' ' +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
216 fmt.text(img.description) +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
217 '---' +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
218 fmt.text(repr(img.exif)))
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
219