I've been working on this problem for a little while and have come across 3 main ways of doing this:
- Generate thumbnail images at the point of upload as a background process.
- Generate images on demand through the main application
- Generate images on demand using the URL as an API
Each approach has its pros and cons.
- This approach is the most restrictive, you have to know all the uses and sizes of thumbnails up front so that you can generate them immediately after upload. The main advantage is that the images can be served efficiently using a server like nginx and are just like any other static resources.
- Django has a library called sorl-thumbnail which provides a template tag for generating thumbnails of all kinds as and when they are needed. It uses a fast key/value store to keep track of what thumbnails have been generated, and invalidates stale generated images automatically if it detects the source image has been changed. The template tag then returns the URL for the generated image, which can be served directly from nginx without going through a scripting layer. More flexible than 1, but you can't (for example) generate an image URL using JavaScript and expect it to exist, it has to be done by the website's backend code or templates.
- Fully dynamic and flexible, you can get whatever version of the image you want just by tweaking the URL, Amazon uses this method as do all those placeholder image generation websites. Can generate URLs in JavaScript and do whatever fancy things you want. The website itself doesn't need any knowledge of the thumbnailing layer short of maybe a few helper methods to generate the URLs for you. BUT, this is obviously the most resource-intensive way of doing things and you need to make sure your architecture can handle the load. You need to use every trick in the book to invalidate caches in a timely manner, avoid unnecessary hits on the resizing script etc.
I'm a big fan of the 3rd way of doing things, I like image generation to be completely isolated from my main website functionality and I like the considerable flexibility, but you need to know what you're doing when it comes to configuring your servers to handle it.