Opened 18 years ago

Closed 18 years ago

Last modified 17 years ago

#961 closed enhancement (wontfix)

[patch] Add automatic thumbnail generation to ImageFields

Reported by: dcwatson@… Owned by: Adrian Holovaty
Component: Core (Other) Version:
Severity: normal Keywords:
Cc: nesh@…, cmlenz@… Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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.

Attachments (6)

thumbnailing.diff (4.5 KB ) - added by dcwatson@… 18 years ago.
image_tags.py (6.6 KB ) - added by Nebojša Đorđević - nesh <nesh@…> 18 years ago.
img filter implementation
new_thumb.diff (9.0 KB ) - added by Nebojša Đorđević - nesh <nesh@…> 18 years ago.
new thumbnail patch
thumbnailing2.diff (5.8 KB ) - added by dcwatson@… 18 years ago.
second stab: thumb_mode, automatic deletion
thumbnails.zip (4.8 KB ) - added by Nebojša Đorđević - nesh <nesh@…> 18 years ago.
thumbnails implementation
meta.diff (742 bytes ) - added by Nebojša Đorđević - nesh <nesh@…> 18 years ago.
small patch for core/meta/init.py

Download all attachments as: .zip

Change History (22)

by dcwatson@…, 18 years ago

Attachment: thumbnailing.diff added

comment:1 by Tom Tobin <korpios@…>, 18 years ago

Isn't an import of a third-party library something Django tries to avoid?

comment:2 by dcwatson@…, 18 years ago

ImageFields already require PIL anyway.

comment:3 by Tom Tobin <korpios@…>, 18 years ago

Ah, you got me there. :-)

comment:4 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

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.

by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Attachment: image_tags.py added

img filter implementation

comment:5 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Cc: nesh@… added

comment:6 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

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

by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Attachment: new_thumb.diff added

new thumbnail patch

comment:7 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

one more thing:

  • if thumbnail do not exist (for example if PIL is not available) it will return original image url

by dcwatson@…, 18 years ago

Attachment: thumbnailing2.diff added

second stab: thumb_mode, automatic deletion

comment:8 by dcwatson@…, 18 years ago

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.

comment:9 by anonymous, 18 years ago

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.

comment:10 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

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


PS. I'll move this discussion to django-devel list to attract more opinions.

by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Attachment: thumbnails.zip added

thumbnails implementation

by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Attachment: meta.diff added

small patch for core/meta/init.py

comment:11 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

Here is a implementation of new ImageWithThumbnailField (thumbnails.zip) with corresponding filters. Put it somewhere into python path under directory nesh/ (currently imports are set this way).

Also source:django/trunk/django/core/meta/__init__.py (meta.diff) patch to enable me to hook-up to model delete method.

Only a |crop filter is not implemented - it fill require new additions to field class to manage crop thumbnails deletion.

comment:12 by Nebojša Đorđević - nesh <nesh@…>, 18 years ago

As is discused in django-devel I'm dropping out of custom ImageField because it's not possible to attach to save/delete events in the model from field without patching django source.

comment:13 by Christopher Lenz <cmlenz@…>, 18 years ago

Cc: cmlenz@… added

comment:14 by Jacob, 18 years ago

Resolution: wontfix
Status: newclosed

This is out of the scope of what Django should do out of the box. In .92 it'll be very easy to define new field types, so this should become an add-on field type.

comment:15 by Nebojsa Djordjevic <nesh at studioquattro dot co dot yu>, 18 years ago

OK with me, I'm started to work on new ImageWithThumbnail field for m-r branch already.

comment:16 by kr0n@…, 18 years ago

So, for people like me, trying to figure out what happens with this:

http://djangoutils.python-hosting.com/wiki/Thumbnails

Note: See TracTickets for help on using tickets.
Back to Top