Recently I’ve been working on a project to move our photo experience to store images on Amazon’s S3 service instead of the local server, in hopes to gain performance and move away from handling the maintenance static files tend to have.
There are many examples online of saving directly to Amazon and not using Django’s Storage Backend, however these examples tend to not give the best overall experience, specially when the site is for a customer. Why keep files on Amazon after a customer has deleted the relationship on your site? Paying for the extra space is something I’m not looking to do.
Luckily during this search I learned about Django’s Storage API and loved the concept and found a great package called django-storage that already has implemented S3 support. The documentation could use a bit of work, but isn’t too hard to get a handle of.
Now that I had the capability to save images to S3 I also wanted the possibility to resize said image and create a thumbnail.
The issue with this is that all examples I could find where in regards to either files saved on disk or stored in memory, neither of which was my case.
Below is example code that allows you to resize images using Django’s models.ImageField and PIL library. Hopefully this saves someone some time as it took me a few hours to come up with a solution.
import urllib2 as urllib
from PIL import Image
from cStringIO import StringIO
from django.core.files.uploadedfile import SimpleUploadedFile
'''Open original photo which we want to resize using PIL's Image object'''
img_file = urllib.urlopen(self.image.url)
im = StringIO(img_file.read())
resized_image = Image.open(im)
'''Convert to RGB if necessary'''
if resized_image.mode not in ('L', 'RGB'):
resized_image = resized_image.convert('RGB')
'''We use our PIL Image object to create the resized image, which already
has a thumbnail() convenicne method that constrains proportions.
Additionally, we use Image.ANTIALIAS to make the image look better.
Without antialiasing the image pattern artificats may reulst.'''
'''Save the resized image'''
temp_handle = StringIO()
''' Save to the image field'''
suf = SimpleUploadedFile(os.path.split(self.image.name)[-1].split('.'),
self.image.save('%s.jpg' % suf.name, suf, save=True)