|
1 | 1 | import binascii |
2 | 2 | import hashlib |
3 | 3 | import os |
| 4 | +from contextlib import closing |
4 | 5 | from io import BytesIO |
5 | 6 |
|
6 | 7 | from django.core.files import File |
@@ -142,38 +143,38 @@ def create_thumbnail(self, width, height=None, quality=None): |
142 | 143 | orig = self.avatar.storage.open(self.avatar.name, "rb") |
143 | 144 | except IOError: |
144 | 145 | return # What should we do here? Render a "sorry, didn't work" img? |
145 | | - try: |
146 | | - image = Image.open(orig) |
147 | | - image = self.transpose_image(image) |
148 | | - quality = quality or settings.AVATAR_THUMB_QUALITY |
149 | | - w, h = image.size |
150 | | - if w != width or h != height: |
151 | | - ratioReal = 1.0 * w / h |
152 | | - ratioWant = 1.0 * width / height |
153 | | - if ratioReal > ratioWant: |
154 | | - diff = int((w - (h * ratioWant)) / 2) |
155 | | - image = image.crop((diff, 0, w - diff, h)) |
156 | | - elif ratioReal < ratioWant: |
157 | | - diff = int((h - (w / ratioWant)) / 2) |
158 | | - image = image.crop((0, diff, w, h - diff)) |
159 | | - if settings.AVATAR_THUMB_FORMAT == "JPEG" and image.mode == "RGBA": |
160 | | - image = image.convert("RGB") |
161 | | - elif image.mode not in (settings.AVATAR_THUMB_MODES): |
162 | | - image = image.convert(settings.AVATAR_THUMB_MODES[0]) |
163 | | - image = image.resize((width, height), settings.AVATAR_RESIZE_METHOD) |
164 | | - thumb = BytesIO() |
165 | | - image.save(thumb, settings.AVATAR_THUMB_FORMAT, quality=quality) |
166 | | - thumb_file = ContentFile(thumb.getvalue()) |
167 | | - else: |
| 146 | + |
| 147 | + with closing(orig): |
| 148 | + try: |
| 149 | + image = Image.open(orig) |
| 150 | + except IOError: |
168 | 151 | thumb_file = File(orig) |
| 152 | + else: |
| 153 | + image = self.transpose_image(image) |
| 154 | + quality = quality or settings.AVATAR_THUMB_QUALITY |
| 155 | + w, h = image.size |
| 156 | + if w != width or h != height: |
| 157 | + ratioReal = 1.0 * w / h |
| 158 | + ratioWant = 1.0 * width / height |
| 159 | + if ratioReal > ratioWant: |
| 160 | + diff = int((w - (h * ratioWant)) / 2) |
| 161 | + image = image.crop((diff, 0, w - diff, h)) |
| 162 | + elif ratioReal < ratioWant: |
| 163 | + diff = int((h - (w / ratioWant)) / 2) |
| 164 | + image = image.crop((0, diff, w, h - diff)) |
| 165 | + if settings.AVATAR_THUMB_FORMAT == "JPEG" and image.mode == "RGBA": |
| 166 | + image = image.convert("RGB") |
| 167 | + elif image.mode not in (settings.AVATAR_THUMB_MODES): |
| 168 | + image = image.convert(settings.AVATAR_THUMB_MODES[0]) |
| 169 | + image = image.resize((width, height), settings.AVATAR_RESIZE_METHOD) |
| 170 | + thumb = BytesIO() |
| 171 | + image.save(thumb, settings.AVATAR_THUMB_FORMAT, quality=quality) |
| 172 | + thumb_file = ContentFile(thumb.getvalue()) |
| 173 | + else: |
| 174 | + thumb_file = File(orig) |
169 | 175 | thumb_name = self.avatar_name(width, height) |
170 | 176 | thumb = self.avatar.storage.save(thumb_name, thumb_file) |
171 | | - except IOError: |
172 | | - thumb_file = File(orig) |
173 | | - thumb = self.avatar.storage.save( |
174 | | - self.avatar_name(width, height), thumb_file |
175 | | - ) |
176 | | - invalidate_cache(self.user, width, height) |
| 177 | + invalidate_cache(self.user, width, height) |
177 | 178 |
|
178 | 179 | def avatar_url(self, width, height=None): |
179 | 180 | return self.avatar.storage.url(self.avatar_name(width, height)) |
|
0 commit comments