Opened 10 years ago

Closed 9 years ago

Last modified 9 years ago

#961 closed enhancement (wontfix)

[patch] Add automatic thumbnail generation to ImageFields

Reported by: dcwatson@… Owned by: adrian
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: UI/UX:

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

Download all attachments as: .zip

Change History (22)

Changed 10 years ago by dcwatson@…

comment:1 Changed 10 years ago by Tom Tobin <korpios@…>

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

comment:2 Changed 10 years ago by dcwatson@…

ImageFields already require PIL anyway.

comment:3 Changed 10 years ago by Tom Tobin <korpios@…>

Ah, you got me there. :-)

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

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.

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

img filter implementation

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

  • Cc nesh@… added

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

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

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

new thumbnail patch

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

one more thing:

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

Changed 10 years ago by dcwatson@…

second stab: thumb_mode, automatic deletion

comment:8 Changed 10 years ago by dcwatson@…

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 Changed 10 years ago 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.

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

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.

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

thumbnails implementation

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

small patch for core/meta/init.py

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

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 Changed 10 years ago by Nebojša Đorđević - nesh <nesh@…>

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 Changed 9 years ago by Christopher Lenz <cmlenz@…>

  • Cc cmlenz@… added

comment:14 Changed 9 years ago by jacob

  • Resolution set to wontfix
  • Status changed from new to closed

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 Changed 9 years ago by Nebojsa Djordjevic <nesh at studioquattro dot co dot yu>

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

comment:16 Changed 9 years ago by kr0n@…

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