I normally like to write code myself instead of installing some large script just to do one task for me. There were a few scripts out there that could create thumbnails, but I wanted something simple and wouldn’t use most of those features. Plus, I wanted to know how to use the Python Image Library with Django 1.0 and learn on my own how to take an uploaded picture and create a few thumbnails of them.
After searching for a while I was able to piece some things together to get something working. In my model I added these two functions.
def thumbnailed(self, file, width, height): from django.core.files.base import ContentFile from StringIO import StringIO import Image try: size = width, height tmp_file = StringIO() im = Image.open(StringIO(file.read())) format = im.format # since new im won't have format if format == "gif" or format == "GIF": im = im.convert("RGB") im.thumbnail(size, Image.ANTIALIAS) if format == "gif" or format == "GIF": im = im.convert("P", dither=Image.NONE, palette=Image.ADAPTIVE) im.save(tmp_file, format, quality=95) except IOError: return None return ContentFile(tmp_file.getvalue())
Using StringIO I was able to create a temporary file in memory to hold the thumbnail data and return it where it would later be passed to django. I was trying to create 3 thumbnails which presented another problem: django was obliterating the uploaded file and the data in my temp files when I was saving. So I figured out how to get around that, but there may be better ways.
def create_thumbnails(self, file): pic = self.thumbnailed(file, 160, 400) if pic is not None: self.picture.save(file.name, pic, save=False) # Django's InMemoryUploadedFile uses StringIO # This will reset it to be ready to use again file.seek(0) thumb = self.thumbnailed(file, 288, 96) if thumb is not None: self.thumbnail.save(file.name, thumb, save=False) # Django's InMemoryUploadedFile uses StringIO # This will reset it to be ready to use again file.seek(0) tiny = self.thumbnailed(file, 144, 48) if tiny is not None: self.tiny_image.save(file.name, tiny, save=False)
The model has picture, thumbnail, and tiny_image as ImageFields and create_thumbnails was originally called from the view and passed the uploaded file from request.FILES.
There was a lot of trial and error trying to get this together, so I hope it helps someone get past that.
Updated July 10, 2009
I added a condition to check if the image is a gif. If it is, it is converted so that the thumnails will look much better than they would without converting them. I also set the quality to 95 so that all images will have the best possible thumbnails.
- How to Write Django Template Tags Template tags can be useful for making your applications more reusable by other projects. For this example I will be...
- How to Write Reusable Apps for Pinax and Django Pinax is a collection of reusable django apps that brings together features that are common to many websites. It...
- Django RequestContext Example Browsing other peoples’ code is a great way to learn new things about a language or framework. I never made...