equal
deleted
inserted
replaced
|
1 """ |
|
2 Utility functions for handling images. |
|
3 |
|
4 Requires PIL, as you might imagine. |
|
5 """ |
|
6 |
|
7 from django.core.files import File |
|
8 |
|
9 class ImageFile(File): |
|
10 """ |
|
11 A mixin for use alongside django.core.files.base.File, which provides |
|
12 additional features for dealing with images. |
|
13 """ |
|
14 def _get_width(self): |
|
15 return self._get_image_dimensions()[0] |
|
16 width = property(_get_width) |
|
17 |
|
18 def _get_height(self): |
|
19 return self._get_image_dimensions()[1] |
|
20 height = property(_get_height) |
|
21 |
|
22 def _get_image_dimensions(self): |
|
23 if not hasattr(self, '_dimensions_cache'): |
|
24 close = self.closed |
|
25 self.open() |
|
26 self._dimensions_cache = get_image_dimensions(self) |
|
27 if close: |
|
28 self.close() |
|
29 return self._dimensions_cache |
|
30 |
|
31 def get_image_dimensions(file_or_path): |
|
32 """Returns the (width, height) of an image, given an open file or a path.""" |
|
33 # Try to import PIL in either of the two ways it can end up installed. |
|
34 try: |
|
35 from PIL import ImageFile as PILImageFile |
|
36 except ImportError: |
|
37 import ImageFile as PILImageFile |
|
38 |
|
39 p = PILImageFile.Parser() |
|
40 close = False |
|
41 if hasattr(file_or_path, 'read'): |
|
42 file = file_or_path |
|
43 else: |
|
44 file = open(file_or_path, 'rb') |
|
45 close = True |
|
46 try: |
|
47 while 1: |
|
48 data = file.read(1024) |
|
49 if not data: |
|
50 break |
|
51 p.feed(data) |
|
52 if p.image: |
|
53 return p.image.size |
|
54 return None |
|
55 finally: |
|
56 if close: |
|
57 file.close() |