Django: Ticket #961: [patch] Add automatic thumbnail generation to ImageFieldshttps://code.djangoproject.com/ticket/961
<p>
There was some discussion about this in <a class="closed ticket" href="https://code.djangoproject.com/ticket/425" title="#425: enhancement: django.utils.images should have a thumbnail function (closed: wontfix)">#425</a> and <a class="closed ticket" href="https://code.djangoproject.com/ticket/674" title="#674: defect: ImageField display use undocumented thumbnails for change_list display (closed: fixed)">#674</a>. Attached is a patch that will use PIL to automatically generate and save thumbnails of various sizes when saving an ImageField. Noteworthy changes:
</p>
<ul><li>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.
</li></ul><ul><li>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.
</li></ul>en-usDjangohttps://www.djangoproject.com/s/img/site/hdr_logo.gifhttps://code.djangoproject.com/ticket/961
Trac 1.2.2dcwatson@…Tue, 29 Nov 2005 20:03:38 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>thumbnailing.diff</em>
</li>
</ul>
TicketTom Tobin <korpios@…>Tue, 29 Nov 2005 20:18:59 GMThttps://code.djangoproject.com/ticket/961#comment:1
https://code.djangoproject.com/ticket/961#comment:1
<p>
Isn't an import of a third-party library something Django tries to avoid?
</p>
Ticketdcwatson@…Tue, 29 Nov 2005 20:27:47 GMThttps://code.djangoproject.com/ticket/961#comment:2
https://code.djangoproject.com/ticket/961#comment:2
<p>
ImageFields already require PIL anyway.
</p>
TicketTom Tobin <korpios@…>Tue, 29 Nov 2005 20:43:06 GMThttps://code.djangoproject.com/ticket/961#comment:3
https://code.djangoproject.com/ticket/961#comment:3
<p>
Ah, you got me there. <code>:-)</code>
</p>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 11:21:46 GMThttps://code.djangoproject.com/ticket/961#comment:4
https://code.djangoproject.com/ticket/961#comment:4
<p>
Well I'm using a different approach for this, instead wiring-up thumbnails into ImageField I'm using <strong>img</strong> filter (attached) to display all images.
</p>
<p>
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.
</p>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 11:22:17 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>image_tags.py</em>
</li>
</ul>
<p>
img filter implementation
</p>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 11:23:14 GMTcc sethttps://code.djangoproject.com/ticket/961#comment:5
https://code.djangoproject.com/ticket/961#comment:5
<ul>
<li><strong>cc</strong>
<em>nesh@…</em> added
</li>
</ul>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 13:59:33 GMThttps://code.djangoproject.com/ticket/961#comment:6
https://code.djangoproject.com/ticket/961#comment:6
<p>
This is a new implementation for automatic thumbnail generation (new_thumb.diff).
</p>
<p>
Main differences
</p>
<ul><li>no changes in ImageField, only get_%s_thumbnail method is added
</li><li>thumbnails are generated on the first request
</li><li>you can specify width and height
</li><li>all thumbnails are deleted when corresponding object is deleted
</li><li>if original image is changed thumbnail is recreated
</li><li>added a bunch of other image related helper functions to photos.py
</li></ul>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 13:59:58 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>new_thumb.diff</em>
</li>
</ul>
<p>
new thumbnail patch
</p>
TicketNebojša Đorđević - nesh <nesh@…>Wed, 30 Nov 2005 14:04:21 GMThttps://code.djangoproject.com/ticket/961#comment:7
https://code.djangoproject.com/ticket/961#comment:7
<p>
one more thing:
</p>
<ul><li>if thumbnail do not exist (for example if PIL is not available) it will return original image url
</li></ul>
Ticketdcwatson@…Wed, 30 Nov 2005 20:19:38 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>thumbnailing2.diff</em>
</li>
</ul>
<p>
second stab: thumb_mode, automatic deletion
</p>
Ticketdcwatson@…Wed, 30 Nov 2005 20:31:04 GMThttps://code.djangoproject.com/ticket/961#comment:8
https://code.djangoproject.com/ticket/961#comment:8
<p>
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?
</p>
<p>
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.
</p>
TicketanonymousWed, 30 Nov 2005 23:50:00 GMThttps://code.djangoproject.com/ticket/961#comment:9
https://code.djangoproject.com/ticket/961#comment:9
<p>
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.
</p>
TicketNebojša Đorđević - nesh <nesh@…>Thu, 01 Dec 2005 08:24:44 GMThttps://code.djangoproject.com/ticket/961#comment:10
https://code.djangoproject.com/ticket/961#comment:10
<blockquote class="citation">
<p>
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.
</p>
</blockquote>
<p>
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.
</p>
<blockquote class="citation">
<p>
Also, it seems like being able to specify arbitrary sizes (in both dimensions) is overkill -- who wants to change a thumbnail's aspect ratio?
</p>
</blockquote>
<p>
Actually, PIL function <code>thumbnail</code> always preserves aspect ratio, so required dimensions are just a request for <strong>no larger than</strong> size with preserving aspect ratio.
</p>
<blockquote class="citation">
<p>
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).
</p>
</blockquote>
<p>
"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).
</p>
<p>
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.
</p>
<p>
Some new tag/filters proposals:
</p>
<ul><li><code>|thumbnail:"w=&lt;width&gt;|h=&lt;height&gt;"</code> - get and/or generate thumbnail with required width and/or height. Works only with ImageFields
</li><li><code>|crop_image:"top=&lt;x&gt;|left=&lt;y&gt;|w=&lt;width&gt;|h=&lt;height&gt;"</code> - crop image from (top, left) position to size (width, height).
</li><li><code> {% image_size &lt;url&gt; as w, h %} </code> - store image size in w and h variables in current context.
</li><li><code>|image_width</code>, <code>|image_height</code> - as alternative to above
</li></ul><p>
PS. I'll move this discussion to <a class="ext-link" href="http://groups-beta.google.com/group/django-developers"><span class="icon">​</span>django-devel</a> list to attract more opinions.
</p>
TicketNebojša Đorđević - nesh <nesh@…>Thu, 01 Dec 2005 13:48:20 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>thumbnails.zip</em>
</li>
</ul>
<p>
thumbnails implementation
</p>
TicketNebojša Đorđević - nesh <nesh@…>Thu, 01 Dec 2005 13:49:07 GMTattachment sethttps://code.djangoproject.com/ticket/961
https://code.djangoproject.com/ticket/961
<ul>
<li><strong>attachment</strong>
set to <em>meta.diff</em>
</li>
</ul>
<p>
small patch for core/meta/<span class="underline">init</span>.py
</p>
TicketNebojša Đorđević - nesh <nesh@…>Thu, 01 Dec 2005 13:56:27 GMThttps://code.djangoproject.com/ticket/961#comment:11
https://code.djangoproject.com/ticket/961#comment:11
<p>
Here is a implementation of new ImageWithThumbnailField (<code>thumbnails.zip</code>) with corresponding filters. Put it somewhere into python path under directory <code> nesh/ </code> (currently imports are set this way).
</p>
<p>
Also source:django/trunk/django/core/meta/__init__.py (<code>meta.diff</code>) patch to enable me to hook-up to model delete method.
</p>
<p>
Only a <code>|crop</code> filter is not implemented - it fill require new additions to field class to manage crop <em>thumbnails</em> deletion.
</p>
TicketNebojša Đorđević - nesh <nesh@…>Thu, 01 Dec 2005 18:01:37 GMThttps://code.djangoproject.com/ticket/961#comment:12
https://code.djangoproject.com/ticket/961#comment:12
<p>
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.
</p>
TicketChristopher Lenz <cmlenz@…>Wed, 22 Feb 2006 17:13:06 GMTcc changedhttps://code.djangoproject.com/ticket/961#comment:13
https://code.djangoproject.com/ticket/961#comment:13
<ul>
<li><strong>cc</strong>
<em>cmlenz@…</em> added
</li>
</ul>
TicketJacobMon, 27 Feb 2006 21:53:54 GMTstatus changed; resolution sethttps://code.djangoproject.com/ticket/961#comment:14
https://code.djangoproject.com/ticket/961#comment:14
<ul>
<li><strong>status</strong>
changed from <em>new</em> to <em>closed</em>
</li>
<li><strong>resolution</strong>
set to <em>wontfix</em>
</li>
</ul>
<p>
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.
</p>
TicketNebojsa Djordjevic <nesh at studioquattro dot co dot yu>Tue, 28 Feb 2006 09:59:31 GMThttps://code.djangoproject.com/ticket/961#comment:15
https://code.djangoproject.com/ticket/961#comment:15
<p>
OK with me, I'm started to work on new ImageWithThumbnail field for m-r branch already.
</p>
Ticketkr0n@…Thu, 01 Jun 2006 22:52:40 GMThttps://code.djangoproject.com/ticket/961#comment:16
https://code.djangoproject.com/ticket/961#comment:16
<p>
So, for people like me, trying to figure out what happens with this:
</p>
<p>
<a class="ext-link" href="http://djangoutils.python-hosting.com/wiki/Thumbnails"><span class="icon">​</span>http://djangoutils.python-hosting.com/wiki/Thumbnails</a>
</p>
Ticket