annotate data/plugin/macro/MoinImage.py @ 262:c605998e1123

added MoinImage class and test macro
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 13 Sep 2008 19:28:31 +0200
parents
children 448a086d840c
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
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
10 * access to some EXIF data (cached)
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 # default width, height
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
20 WEBNAIL_SIZE = (640, 480)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
21 THUMBNAIL_SIZE = (128, 128)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
22
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
23 # we don't process and cache all EXIF infos, but just these:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
24 EXIF_CACHED = set(['DateTimeOriginal', 'TimeZoneOffset', 'Orientation', ])
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
25
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
26 import os, time
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
27 import StringIO
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
28
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
29 from MoinMoin import caching, wikiutil
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
30 from MoinMoin.action import AttachFile, cache
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
31
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
32 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
33 import Image
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
34 except ImportError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
35 Image = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
36
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
37 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
38 import ExifTags
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
39 except ImportError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
40 ExifTags = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
41
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
42 class MoinImage(object):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
43 def __init__(self, request,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
44 name, # PageName/AttachName for now, later this is just the item name
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 webnail_size=WEBNAIL_SIZE,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
47 thumbnail_size=THUMBNAIL_SIZE,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
48 ):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
49 self.request = request
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
50 self.pagename, self.attachname = name.rsplit('/', 1)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
51 self.description = description
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
52 self.webnail_size = webnail_size
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
53 self.thumbnail_size = thumbnail_size
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
54
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
55 # cached property values:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
56 self.__filename = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
57 self.__content_type = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
58 self.__cache_key = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
59 self.__image = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
60 self.__exif = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
61 self.__ctime = None
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
62
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
63 def _get_filename(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
64 if self.__filename is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
65 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
66 return self.__filename
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
67 _filename = property(_get_filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
68
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
69 def _get_content_type(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
70 if self.__content_type is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
71 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
72 return self.__content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
73 content_type = property(_get_content_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
74
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
75 def _get_image(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
76 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
77 self.__image = Image.open(self._filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
78 return self.__image
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
79 image = property(_get_image)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
80
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
81 def _get_cache_key(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
82 if self.__cache_key is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
83 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
84 return self.__cache_key
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
85 _cache_key = property(_get_cache_key)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
86
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
87 def _get_exif_data(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
88 """ 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
89 if self.__exif is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
90 key = self._cache_key
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
91 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
92 use_pickle=True, do_locking=False)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
93 if not exif_cache.exists():
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
94 # 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
95 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
96 exif_data = {}
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
97 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
98 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
99 tag_name = ExifTags.TAGS.get(tag)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
100 if tag_name in EXIF_CACHED:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
101 exif_data[tag_name] = value
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 time_str = exif_data['DateTimeOriginal']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
104 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
105 t = time.mktime(tm)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
106 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
107 tz_str = exif_data['TimeZoneOffset']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
108 tz_offset = int(tz_str) * 3600
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 tz_offset = 0
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
111 # 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
112 t -= time.timezone + tz_offset
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
113 except:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
114 t = 0
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
115 exif_data['DateTimeOriginal'] = t
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
116 except (IOError, AttributeError):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
117 exif_data = {}
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
118 exif_cache.update(exif_data)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
119 self.__exif = exif_data
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
120 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
121 self.__exif = exif_cache.content()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
122 return self.__exif
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
123 exif = property(_get_exif_data)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
124
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
125 def _get_ctime(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
126 """ 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
127 if self.__ctime is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
128 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
129 ctime = self.exif['DateTimeOriginal']
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
130 except KeyError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
131 ctime = os.path.getctime(self._filename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
132 self.__ctime = ctime
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
133 return self.__ctime
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
134 ctime = property(_get_ctime)
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 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
137 """ 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
138 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
139 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
140 if content_type is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
141 content_type = self.content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
142 if content_type == 'image/jpeg':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
143 output_type = 'JPEG'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
144 elif content_type == 'image/png':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
145 output_type = 'PNG'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
146 elif content_type == 'image/gif':
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
147 output_type = 'GIF'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
148 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
149 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
150 image = self.image
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
151 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
152 try:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
153 # 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
154 # 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
155 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
156 except KeyError:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
157 transpose_op = 1 # no change
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 if size is not None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
160 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
161 image.thumbnail(size, Image.ANTIALIAS)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
162
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
163 transpose_func = {
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
164 1: lambda image: image,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
165 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
166 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
167 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
168 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
169 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
170 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
171 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
172 }
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
173 image = transpose_func[transpose_op](image)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
174
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
175 buf = StringIO.StringIO()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
176 image.save(buf, output_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
177 buf.flush() # XXX needed?
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
178 data = buf.getvalue()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
179 buf.close()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
180 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
181 data = ''
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
182 return content_type, data
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
183
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
184 def _cache_url(self, size=None):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
185 """ return a cache url for a rendering of this image with specified size,
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
186 make sure the cache contains that rendering.
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
187 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
188 request = self.request
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
189 content_type = self.content_type
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
190 if size is None:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
191 size_str = 'orig'
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
192 else:
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
193 size_str = '%d_%d' % size
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
194 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
195 if not cache.exists(request, key):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
196 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
197 cache.put(request, key, data, content_type=content_type)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
198 return cache.url(self.request, key)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
199
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
200 def webnail_url(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
201 """ return url of webnail of this image """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
202 return self._cache_url(self.webnail_size)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
203
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
204 def thumbnail_url(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
205 """ return url of thumbnail of this image """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
206 return self._cache_url(self.thumbnail_size)
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 def fullsize_url(self):
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
209 """ return url of non-resized, but maybe transposed original image """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
210 return self._cache_url() # keep size as is
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
211
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
212
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
213 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
214 """ 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
215 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
216
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
217 <<MoinImage(PageName/attachname,sample image)>>
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
218 """
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
219 request = macro.request
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
220 fmt = macro.formatter
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
221 thispagename = fmt.page.page_name
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
222 pagename, fname = AttachFile.absoluteName(itemname, thispagename)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
223 img = MoinImage(request, itemname, desc)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
224
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
225 src = img.fullsize_url()
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
226 alt = fmt.text(img.description)
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
227 return (fmt.image(src=src, alt=alt) +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
228 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
229 ' ' +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
230 fmt.text(img.description) +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
231 '---' +
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
232 fmt.text(repr(img.exif)))
c605998e1123 added MoinImage class and test macro
Thomas Waldmann <tw AT waldmann-edv DOT de>
parents:
diff changeset
233