Created
June 7, 2013 22:03
-
-
Save mmlin/5732731 to your computer and use it in GitHub Desktop.
Django - Create thumbnail on model save. Creates a thumbnail when saving a model by cropping it to square and resizing to 280x280. The thumbnail is not created if the original image is smaller than 280x280, doesn't exist, or if a thumbnail already exists.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from cStringIO import StringIO | |
from django.core.files.base import ContentFile | |
from django.db import models | |
from PIL import Image | |
class SomeModel(models.Model): | |
image = models.ImageField(upload_to='images', blank=True) | |
thumbnail = models.ImageField(upload_to='thumbnails', blank=True) | |
def create_thumbnail(self): | |
# Don't do anything if there is no image to thumbnail. | |
# Also, don't overwrite an existing thumbnail | |
# (prevents a new thumbnail from being created every save). | |
if not self.image or self.thumbnail: | |
return | |
image = Image.open(self.image.file) | |
# If the image is smaller than 280 x 280, | |
# don't bother creating a thumbnail. | |
width, height = image.size | |
if width < 280 or height < 280: | |
return | |
# Crop as little as possible to square, keeping the center. | |
if width > height: | |
delta = width - height | |
left = int(delta / 2) | |
upper = 0 | |
right = height + left | |
lower = height | |
else: | |
delta = height - width | |
left = 0 | |
upper = int(delta / 2) | |
right = width | |
lower = width + upper | |
image = image.crop((left, upper, right, lower)) | |
# Create the thumbnail as a 280 x 280 square. | |
image.thumbnail((280, 280), Image.ANTIALIAS) | |
# Save the thumbnail in the FileField. | |
# Using Image.save(content, 'jpeg') seems to work for pngs too. | |
buf = StringIO() | |
image.save(buf, 'jpeg', quality=95) | |
cf = ContentFile(buf.getvalue()) | |
self.thumbnail.save(name=self.image.name, content=cf, save=False) | |
def save(self): | |
self.create_thumbnail() | |
super(SomeModel, self).save() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment