Question

I would like to dynamically create thumbnails based on parameters in the URL. For example, http://mysite.com/images/1234/120x45.jpg would create a 120x45 thumbnail for image id 1234.

The obvious solution to this is to have a django view which does the following:

  1. Look for a previously cached version of the image at this size.
  2. Create a thumbnail if it's not cached (some logic for locking so that only 1 process creates the thumbnail and other processes wait).
  3. Pipe the results through django.

That should "work", but I'm concerned about performance. I don't like the idea of using django to serve static content. What are some other ways to accomplish this problem?

Was it helpful?

Solution

You don't have to use Django to serve the static content directly. Simply have your server route 404 requests for your images folder to a Django view, where it splits apart the filename and generates the appropriate thumbnail, before redirecting back to the original URL (which hopefully will no longer be a 404).

As for the other answer's django-imagekit suggestion, I'm not sure it does anything to let you dynamically generate image thumbs based on URL, but I certainly do recommend using it for all the features it does have.

Edit:

As for the actual URL structure, I feel a more typical /images/filename-120x45.jpg would allow you to more easily filter out 404 requests that have nothing to do with dynamic thumbnail generation. Say, for instance, that there are tons of 404 errors for /images/original_size_image.jpg. You wouldn't want those being routed to Django, and you could only match filenames of that format with regex. [end edit]

You have to be careful though about letting anybody aware of this feature spam your Django app. They could potentially kill it with an infinite number of image size and filename combinations at their fingertips. You would need to figure how to put upper limits on these requests, like redirecting back to a 404 if either dimension is larger than the original, or even figuring out how to cap requests for multiple dimensions of the same image. Maybe this was what you were you getting at when mentioning "locking" though.

As an aside, I see you've tagged Apache but I would really like to recommend that you serve static content through something like Nginx. You could maybe negate the extra overhead of the dynamic image requests if you use a static file server that isn't complete crap at serving static files.

OTHER TIPS

You can also try sorl, it is being used by Satchmo.

See this application to generate thumbs.

Developed in Python, using tornadoweb server.

https://github.com/globocom/thumbor

pip install thumbor

Great Application

I looked up these answers and even though they work they were just too sofisticated for me. If you just want a quick and dirty way to get thumbnails, just using the PIL library might be a good call, this is my code:

file, ext = os.path.splitext('image.jpg')
im = Image.open('/full/path/to/image.jpg')
im.thumbnail(size, Image.ANTIALIAS)
thumb_path = os.path.join('/full/path/to/thumb/dir/', file + ".thumb" + ".jpeg")
im.save(thumb_path)

Download the PIL library here

Cheers, hopes this helps someone.

You can take a peek at the sorl-thumbnail documentation. I use it in almost all of my projects together with serving static content with Nginx from the /media/ dir :)

Check out this discussion page about thumbnail contribution for Django:

https://code.djangoproject.com/wiki/ThumbNails

I had the same exact problem: in a high-traffic site, generating dozens of thumbnails at response time is not feasible, as is generating thumbnails for all past content in batch, so I created an app for that. Check it out: https://github.com/hcarvalhoalves/django-rest-thumbnails

Thumbor indeed is a great service, you can use django-thumbor on django.

pip install django-thumbor

Repo here: https://github.com/ricobl/django-thumbor

You may just need to resize the image on display, based on the specified dimension you need, on demand. The Django Imagefit library does exactly that, and it also gives the possibility to crop.

In your example you would write {{ 'http://example.com/images/1234.jpg'|resize:'120x45' }} and you would end with a 120x45 size image.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top