Add automatic thumbnail generation to ImageFields (from ticket #961)

8 views
Skip to first unread message

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 3:32:26 AM12/1/05
to django-d...@googlegroups.com
As discussed in http://code.djangoproject.com/ticket/961 and also
referenced in http://code.djangoproject.com/ticket/674 and http://
code.djangoproject.com/ticket/425:

Original proposal by dcwa...@gmail.com:
>
> There was some discussion about this in #425 and #674. Attached is
> a patch that will use PIL to automatically generate and save
> thumbnails of various sizes when saving an ImageField?. Noteworthy
> changes:
>
> - ImageFields? may take a thumb_sizes argument, which is a list of
> integers. A thumbnail image is generated for each size, such that
> no side is larger than the given integer.
>
> - Model objects that have ImageFields? with thumb_sizes specified
> will have get_XXX_thumbnail_url and get_XXX_thumbnail_sizes
> methods. The former optionally takes an integer (size) to determine
> which thumbnail url to return. Otherwise it will return the first
> thumbnail in the thumb_sizes list.

discussion
----------

me:

> Well I'm using a different approach for this, instead wiring-up
> thumbnails into ImageField? I'm using img filter (attached) to
> display all images.
>
> Embedding in ImageFiled? have some advantages (like automatic
> removal of thumbnail files) so I will try to merge this two things
> together and report back.

> This is a new implementation for automatic thumbnail generation
> (new_thumb.diff).
>
> Main differences
>
> * no changes in ImageField?, only get_%s_thumbnail method is added
> * thumbnails are generated on the first request
> * you can specify width and height
> * all thumbnails are deleted when corresponding object is deleted
> * if original image is changed thumbnail is recreated
> * added a bunch of other image related helper functions to
> photos.py


dcwa...@gmail.com:

> Maybe it's a matter of personal style, but it seems that most
> applications will want thumbnails at given sizes, and these sizes
> are known to the developer. In that case, generating the thumbnails
> when the image is uploaded makes more sense, as they will be
> readily available the first time they are needed. Also, it seems
> like being able to specify arbitrary sizes (in both dimensions) is
> overkill -- who wants to change a thumbnail's aspect ratio?
>
> In thumbnailing2.diff, I've added automatic thumbnail deletion when
> the original picture is deleted, and a thumb_mode parameter passed
> into ImageField?. Specifying meta.WIDTH and meta.HEIGHT create
> thumbnails with width/height no larger than the values in
> thumb_sizes, while meta.BOTH constrains both width and height while
> maintaining aspect ratio. I also moved generate_thumbnail to
> django.parts.media.photos where it makes more sense.
> Wed 30 Nov 2005 05:50:00 PM CST: Modified by anonymous
>
> Actually what you want - at least what I want, I can't talk about
> your wishes ;-) - is to be able to give the "bounding box" of the
> thumbnail and the choice wether it should be scaled (and leaving
> part of the bounding box empty if your image has a different aspect
> ratio) or cropped (so that it fills the full bounding box, but part
> of the thumbnail is cut to make it fit th ebounding box, if it's
> aspect ratio is different). This because thumbnail size is very
> much a function of the layout, not the code itself - the layout
> later will decide what thumbnail size I need, not the upload of an
> image to the server.

me:
> > Maybe it's a matter of personal style, but it seems that most
> applications will want thumbnails at given sizes, and these sizes
> are known to the developer.
>
> Well, I thing that decision of image sizes is mostly done on the
> designer part (one which works with templates) and not developer.
> Our task (as a developers) is to make possible to designer (or
> template writer) to use whatever thumbnail size he chooses.
>
> > Also, it seems like being able to specify arbitrary sizes (in
> both dimensions) is overkill -- who wants to change a thumbnail's
> aspect ratio?
>
> Actually, PIL function thumbnail always preserves aspect ratio, so
> required dimensions are just a request for no larger than size with
> preserving aspect ratio.
>
> > is to be able to give the "bounding box" of the thumbnail and the
> choice wether it should be scaled (and leaving part of the bounding
> box empty if your image has a different aspect ratio) or cropped
> (so that it fills the full bounding box, but part of the thumbnail
> is cut to make it fit th ebounding box, if it's aspect ratio is
> different).
>
> "bounding box" part is already taken care of with thumbnail
> generation (see above), and "crop box" is very interesting idea
> (and not hard to add IMHO).
>
> IMHO, suggested usage for all of this will be that thumbnail
> infrastructure will be coupled with some additional tags/filters
> (I'll add examples below) for accessing images from templates.
>
> Some new tag/filters proposals:
>
> * |thumbnail:"w=<width>|h=<height>" - get and/or generate
> thumbnail with required width and/or height. Works only with
> ImageFields?
> * |crop_image:"top=<x>|left=<y>|w=<width>|h=<height>" - crop
> image from (top, left) position to size (width, height).
> * {% image_size <url> as w, h %} - store image size in w and h
> variables in current context.
> * |image_width, |image_height - as alternative to above

Any opinions?

---
Nebojša Đorđević - nesh
Studio Quattro - Niš - SCG

http://djnesh.blogspot.com/ | http://djnesh-django.blogspot.com/
Registered Linux User 282159 [http://counter.li.org]



Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 3:38:30 AM12/1/05
to django-d...@googlegroups.com
I'm forgot to mention that I'll make a new ImageThumbnailField (as a
ImageField subclass) witch will implement all of the my proposals
including all of the tags/filters required to make this work.

This way I can experiment with thumbnail generation without
disturbing main trunk.

PythonistL

unread,
Dec 1, 2005, 5:24:57 AM12/1/05
to Django developers
Hi Nebojša,
Do you have a good experience with ImageField ?
I will have to use images in my app. too but not sure about ImageField
.
I am thinking about having an extra integer field that has the same
number as a picture. The picture will be stored separately from the
database and and also a thumbnail that can have a prefix.
E.g. the record will have ID =4100, so appropriate image will be
4100.jpg and a thumbnail T4100.jpg
What do you think of that?
Regards,
L.

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 6:54:57 AM12/1/05
to django-d...@googlegroups.com
Well, I have good experience with ImageField. :)

Only difference with your method and with using ImageField is that
image path is stored (relative to MEDIA_ROOT) instead of integer.
In your example you will be responsible for deleting images/
thumbnails when object is deleted (ImageField does this for you).

And about thumbnails, well, I'm trying to automate this so you will
just need to ask for thumbnail of required size and it will be auto-
magically generated for you (PIL is required), same with object
deletion.

Pedro Furtado

unread,
Dec 1, 2005, 8:14:03 AM12/1/05
to django-d...@googlegroups.com


2005/12/1, Nebojša Đorđević - nesh <ne...@studioquattro.co.yu>:

And about thumbnails, well, I'm trying to automate this so you will
just need to ask for thumbnail of required size and it will be auto-
magically generated for you (PIL is required), same with object
deletion.

Nice!

Amazing how things are going extremely fast here.

--
Pedro

PythonistL

unread,
Dec 1, 2005, 10:40:36 AM12/1/05
to Django developers
Please let know the Django community when you are finished with that.
Any timeline?
Regards,
Lad.

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 10:54:21 AM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 16:40 CET, PythonistL wrote:

> Please let know the Django community when you are finished with that.

First version is attached to #961, it requires to patch django
because that is the only way for me to add some "magic" into model
delete method (see save/delete/etc hooks for custom fields thread).

Other solution is to manually insert call to delete thumbnails in
model _post_delete method.

If this makes into contrib I'll will have to make separate helper
function to delete thumbnails for a given image url and drop auto
deletion (for now).

Radek Svarz

unread,
Dec 1, 2005, 11:52:06 AM12/1/05
to django-d...@googlegroups.com
Hi,

We have been using xt:Commerce for a while and I realized quite nice
approach to organize images. There are several subfolders of media for
product images, like follows:

product_images/original_images
product_images/thumbnail_images
product_images/info_images
product_images/popup_images

where original images (biggest / huge / not ready to show on the web)
are stored for the reference and possible recreation of other sizes
under different conditions when needed.

thumbnail images are list thumbnails (smallest)
info images are images shown on the detail page of the product (middle
size to fit the design)
popup images (big size) are images, when it is clicked on the info
image, so the new window with just the image opens (and closes on
another click on the big image)

I've realized that this is becoming quite a pattern. Would this
correlate with your approach?

Radek

PS: look at the flickr - they have even more sizes

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 12:08:34 PM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 17:52 CET, Radek Svarz wrote:

> I've realized that this is becoming quite a pattern. Would this
> correlate with your approach?

Well, no. I deliberately choose not to have any predefined size for
thumbnails to make things more general. Thumbnails are saved in the
same directory as a original file with following filename pattern:
<name>_t[<width>][_h<height>].<ext> (this is following thumbnail
naming scheme found in admin).

Radek Svarz

unread,
Dec 1, 2005, 12:20:56 PM12/1/05
to django-d...@googlegroups.com
> thumbnails to make things more general. Thumbnails are saved in the
> same directory as a original file with following filename pattern:

OK, but can we make more thumbnails of different sizes from one image
simultaneously?

And can we add options for image decorations? (shadow, watermark, etc.
that PIL allows)

Radek

On 12/1/05, Nebojša Đorđević - nesh <ne...@studioquattro.co.yu> wrote:
>

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 12:52:38 PM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 16:54 CET, Nebojša Đorđević - nesh wrote:

> If this makes into contrib I'll will have to make separate helper
> function to delete thumbnails for a given image url and drop auto
> deletion (for now).

Because I have no other option other than patching django source to
add my custom field I'm completely dropping a custom image field for
now.

My new implementation are filters and some help-full functions for
manipulating images (attached below). If it have enough interest I'll
will post a separate ticket for including into django contrib.

Details follows:

* all of the tags mentioned before are here and usage is the same
* because it's currently not possible to attach to any of save/delete
events from field, you have to add in your models _post_save and
_post_delete hooks. Example:

class myImageModel(meta.Model):
image = meta.ImageField(upload_to=os.path.join(IMG_ROOT))

def _post_save(self):
# make thumbnail for admin
from nesh.thumbnails.utils import make_admin_thumbnail
make_admin_thumbnail(self.image)
#

def _post_delete(self):
# remove thumbnails
from nesh.thumbnails.utils import remove_thumbnails
remove_thumbnails(self.image)
#


nesh.zip

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 12:57:21 PM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 18:20 CET, Radek Svarz wrote:

> OK, but can we make more thumbnails of different sizes from one image
> simultaneously?

Thumbnails are generated on the first request from template (i.e <img
src="{{ url|thumbnail:"width=100" }}" />). You can pre-generate some
sizes in model _post_save if you want.

> And can we add options for image decorations? (shadow, watermark, etc.
> that PIL allows)

This is the matter of just adding a new tags or filters to library.

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 12:58:25 PM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 18:52 CET, Nebojša Đorđević - nesh wrote:

> Details follows

I forgot. Just unpack .zip somewhere in your PYTHONPATH to use it.

Nebojša Đorđević - nesh

unread,
Dec 1, 2005, 1:10:25 PM12/1/05
to django-d...@googlegroups.com
On 2005-12-01, at 18:57 CET, Nebojša Đorđević - nesh wrote:

>
>> OK, but can we make more thumbnails of different sizes from one image
>> simultaneously?
>
> Thumbnails are generated on the first request from template (i.e
> <img src="{{ url|thumbnail:"width=100" }}" />). You can pre-
> generate some sizes in model _post_save if you want.

OTOH it is not a problem to add a multiple thumbnail generator to
thumbnails.utils if I understood you correctly.
Reply all
Reply to author
Forward
0 new messages