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 from PIL import ImageFile as PILImageFile |
|
34 p = PILImageFile.Parser() |
|
35 close = False |
|
36 if hasattr(file_or_path, 'read'): |
|
37 file = file_or_path |
|
38 else: |
|
39 file = open(file_or_path, 'rb') |
|
40 close = True |
|
41 try: |
|
42 while 1: |
|
43 data = file.read(1024) |
|
44 if not data: |
|
45 break |
|
46 p.feed(data) |
|
47 if p.image: |
|
48 return p.image.size |
|
49 return None |
|
50 finally: |
|
51 if close: |
|
52 file.close() |