| 1 | ========================= |
| 2 | django.contrib.thumbnails |
| 3 | ========================= |
| 4 | |
| 5 | The ``django.contrib.thumbnails`` package, part of the `"django.contrib" add-ons`_, |
| 6 | provides a way of thumbnailing images. |
| 7 | |
| 8 | It requires the Python Imaging Library (PIL_). |
| 9 | |
| 10 | .. _"django.contrib" add-ons: ../add_ons/ |
| 11 | .. _PIL: http://www.pythonware.com/products/pil/ |
| 12 | |
| 13 | Template filters |
| 14 | ================ |
| 15 | |
| 16 | To use these template filters, add ``'django.contrib.thumbnails'`` to your |
| 17 | ``INSTALLED_APPS`` setting. Once you've done that, use |
| 18 | ``{% load thumbnails %}`` in a template to give your template access to the |
| 19 | filters. |
| 20 | |
| 21 | The thumbnail creation filters, all very similar in behaviour, are: |
| 22 | |
| 23 | * ``thumbnail`` |
| 24 | * ``thumbnail_crop`` |
| 25 | * ``thumbnail_squash`` |
| 26 | |
| 27 | The only difference between them is the `Thumbnail methods`_ that they use. |
| 28 | |
| 29 | One other filter is provided as a helper to the most common use: |
| 30 | |
| 31 | * ``img_tag`` |
| 32 | |
| 33 | Using the thumbnail filters |
| 34 | --------------------------- |
| 35 | |
| 36 | Usage:: |
| 37 | |
| 38 | <img src="{{ object.imagefield|thumbnail:"150x100" }}" /> |
| 39 | |
| 40 | The filter is applied to a image field (not the url get from |
| 41 | ``get_[field]_url`` method of the model). Supposing the imagefield filename is |
| 42 | ``'image.jpg'``, it creates a thumbnailed image file proportionally resized |
| 43 | down to a maximum of 150 pixels wide and 100 pixels high called |
| 44 | ``'image_150x100_scale_q75.jpg'`` in the same location as the original image |
| 45 | and returns the URL to this thumbnail image. |
| 46 | |
| 47 | The ``thumbnail_crop`` works exactly the same way but uses the crop method |
| 48 | (and the filename would be called ``'image_150x100_crop_q75.jpg'``). Similarly, |
| 49 | ``thumbnail_squash`` resizes the image to exactly the dimensions given |
| 50 | (``'image_150x100_squash_q75.jpg'``). |
| 51 | |
| 52 | If the thumbnail filename already exists, it is only overwritten if the date of |
| 53 | the the original image file is newer than the thumbnail file. |
| 54 | |
| 55 | The ``q75`` refers to the JPEG quality of the thumbnail image. You can change |
| 56 | the quality by providing a third number to the filter:: |
| 57 | |
| 58 | {{ object.imagefield|thumbnail:"150x10 85" }} |
| 59 | |
| 60 | Rather than just outputting the url, you can reference any other properties |
| 61 | (see the ```Thumbnail`` object properties`_ section below for a complete |
| 62 | list):: |
| 63 | |
| 64 | {% with object.imagefield|thumbnail:"150x100" as thumb %} |
| 65 | <img src="{{ thumb.url }}" width="{{ thumb.thumbnail.size.0 }}" height="{{ thumb.thumbnail.size.1 }}" /> |
| 66 | {% endwith %} |
| 67 | |
| 68 | The above example is the most common case, and the ``img_tag`` filter is |
| 69 | provided to make that easier. The following example explains it's use:: |
| 70 | |
| 71 | {{ object.imagefield|thumbnail:"150x100"|img_tag }} |
| 72 | |
| 73 | Creating a thumbnail |
| 74 | ==================== |
| 75 | |
| 76 | The rest of this documentation deals with lower-level usage of thumbnails. |
| 77 | |
| 78 | To create a thumbnail object, simply call the ``Thumbnail`` class:: |
| 79 | |
| 80 | >>> from django.contrib.thumbnails import * |
| 81 | >>> thumbnail = Thumbnail(filename, data, size=(100, 100)) |
| 82 | |
| 83 | The thumbnail object takes the following arguments: |
| 84 | |
| 85 | ================= ========================================================= |
| 86 | Argument Description |
| 87 | ================= ========================================================= |
| 88 | |
| 89 | ``filename`` A string containing the path and filename to use when |
| 90 | saving or retreiving this thumbnail image from disk |
| 91 | (relative to the ``Thumbnail`` object's ``root`` property |
| 92 | which defaults to ``settings.MEDIA_ROOT``). |
| 93 | |
| 94 | For advanced usage, see the ```Thumbnail```_ property |
| 95 | section. |
| 96 | |
| 97 | ``data`` A string or stream of the original image object to be |
| 98 | thumbnailed. If not provided and a file matching the |
| 99 | thumbnail can not be found, ``TemplateNoData`` will be |
| 100 | raised. |
| 101 | |
| 102 | Example:: |
| 103 | |
| 104 | >>> Thumbnail('%(method)/s%(x)sx%(y)s/test.jpg', size=(60, 40)).filename |
| 105 | '.../scale/60x40/test.jpg' |
| 106 | |
| 107 | ``overwrite`` Set to ``True`` to overwrite the thumbnail with ``data`` |
| 108 | even if an existing cached thumbnail is found. Defaults |
| 109 | to ``False``. |
| 110 | |
| 111 | ``size`` The size for the thumbnail image. Required unless using a |
| 112 | subclass which provides a default ``size`` (see the |
| 113 | `Custom thumbnails`_ section below). |
| 114 | |
| 115 | ``jpeg_quality`` Change the quality of the thumbnail image. The default |
| 116 | quality is 75. The PIL manual recommends that values |
| 117 | above 95 should be avoided. |
| 118 | |
| 119 | ``Thumbnail`` object properties |
| 120 | =============================== |
| 121 | |
| 122 | The thumbnail object which is created provides the following properties and |
| 123 | functions: |
| 124 | |
| 125 | ``filename`` |
| 126 | ------------ |
| 127 | |
| 128 | Reading this property returns the full path and filename to this thumbnail |
| 129 | image. |
| 130 | |
| 131 | When you set this property, the filename string you provide is internally |
| 132 | appended to the ``Thumbnail`` object's ``root`` property. |
| 133 | |
| 134 | You can use string formatting to generate the filename based on the |
| 135 | thumbnailing method and size: |
| 136 | |
| 137 | * ``%(x)s`` for the thumbnail target width, |
| 138 | * ``%(y)s`` for the thumbnail target height, |
| 139 | * ``%(method)s`` for the thumbnailing method, |
| 140 | * ``%(jpeg_quality)s`` for the JPEG quality. |
| 141 | |
| 142 | For example:: |
| 143 | |
| 144 | >>> Thumbnail('%(method)/s%(x)sx%(y)s/test.jpg', size=(60, 40)).filename |
| 145 | '.../scale/60x40/test.jpg' |
| 146 | # (where ... is settings.MEDIA_ROOT) |
| 147 | |
| 148 | Note: thumbnailed images are always saved as JPEG images, so if the filename |
| 149 | string does not end in `'.jpg'`, this will be automatically appended to the |
| 150 | thumbnail's filename. |
| 151 | |
| 152 | ``original_image`` |
| 153 | ------------------ |
| 154 | |
| 155 | This read-only property returns a PIL ``Image`` containing the original |
| 156 | image (passed in with ``data``). |
| 157 | |
| 158 | ``thumbnail`` |
| 159 | ------------- |
| 160 | |
| 161 | This read-only property returns a PIL ``Image`` containing the thumbnail |
| 162 | image. |
| 163 | |
| 164 | ``url`` |
| 165 | ------- |
| 166 | |
| 167 | This read-only property returns the full url this thumbnail image. |
| 168 | |
| 169 | It is generated by appending the parsed ``filename`` string to the |
| 170 | ``Template`` object's ``base_url`` property. |
| 171 | |
| 172 | ``delete()`` |
| 173 | ------------ |
| 174 | |
| 175 | Call this function to delete the thumbnail file if it exists on the disk. |
| 176 | |
| 177 | Custom thumbnails |
| 178 | ================= |
| 179 | |
| 180 | Similar to newforms, you can create a subclass to override the default |
| 181 | properties of the ``Thumbnail`` base class:: |
| 182 | |
| 183 | from django.contrib.thumbnails import Thumbnail |
| 184 | |
| 185 | class MyThumbnail(Thumbnail): |
| 186 | size = (100, 100) |
| 187 | |
| 188 | Here are the properties you can provide to your subclass: |
| 189 | |
| 190 | =============== =========================================================== |
| 191 | Property Description |
| 192 | =============== =========================================================== |
| 193 | |
| 194 | ``size`` Default size for creating thumbnails (no default). |
| 195 | ``base_url`` Base url for thumbnails (default is ``settings.MEDIA_URL``). |
| 196 | ``root`` Base directory for thumbnails (default is |
| 197 | ``settings.MEDIA_ROOT``). |
| 198 | ``method`` The thumbnailing funciton to use (default is ``scale``). |
| 199 | See the `Thumbnail methods`_ section below. |
| 200 | |
| 201 | Thumbnail methods |
| 202 | ================= |
| 203 | |
| 204 | There are several thumbnailing methods available in |
| 205 | ``django.contrib.thumbnails.methods`` |
| 206 | |
| 207 | ``crop()`` |
| 208 | ---------- |
| 209 | |
| 210 | This method crops the image height or width to match the ratio of the thumbnail |
| 211 | ``size`` and then resizes it down to exactly the dimensions of ``size``. |
| 212 | |
| 213 | It requires the original image to be both as wide and as high as ``size``. |
| 214 | |
| 215 | ``scale()`` |
| 216 | ----------- |
| 217 | |
| 218 | This is the normal PIL scaling method of proportionally resizing the image down |
| 219 | to no greater than the thumbnail ``size`` dimensions. |
| 220 | |
| 221 | It requires the original image to be either as wide or as high as ``size``. |
| 222 | |
| 223 | ``squash()`` |
| 224 | ------------ |
| 225 | |
| 226 | This method resizes the image down to exactly the dimensions given. This will |
| 227 | potentially squash or stretch the image. |
| 228 | |
| 229 | It requires the original image to be both as wide and as high as ``size``. |
| 230 | |
| 231 | Making your own methods |
| 232 | ----------------------- |
| 233 | |
| 234 | To make your own thumbnailing function, create a function which accepts one |
| 235 | parameter (``thumbnail``) and returns a PIL ``Image``. |
| 236 | |
| 237 | The ``thumbnail`` parameter will be a ``Thumbnail`` object, so you can use it |
| 238 | to get the original image (it will raise ``ThumbnailNoData`` if no data was |
| 239 | provided) and the thumbnail size:: |
| 240 | |
| 241 | img = thumbnail.original_image |
| 242 | size = thumbnail.size |
| 243 | |
| 244 | Exceptions |
| 245 | ========== |
| 246 | |
| 247 | The following exceptions (all found in ``django.contrib.thumbnails.exceptions`` |
| 248 | and all subclasses of ``ThumbnailException``) could be raised when using the |
| 249 | ``Thumbnail`` object: |
| 250 | |
| 251 | ========================= ================================================ |
| 252 | Exception Reason |
| 253 | ========================= ================================================ |
| 254 | |
| 255 | ``ThumbnailNoData`` Tried to get the ``original_image`` when no |
| 256 | ``data`` was provided or tried to get the |
| 257 | ``url`` when the file did not exist and no |
| 258 | ``data`` was provided. |
| 259 | ``ThumbnailTooSmall`` The ``original_image`` was too small to |
| 260 | thumbnail using the given thumbnailing method. |
| 261 | ``ThumbnailInvalidImage`` The ``data`` provided could not be decoded to |
| 262 | a valid image format (or more rarely, using |
| 263 | ``thumbnail`` to retreive an existing thumbnail |
| 264 | file from disk which could not be decoded to a |
| 265 | valid image format). |
| 266 | |
| 267 | Putting it all together |
| 268 | ======================= |
| 269 | |
| 270 | Here is a snippet of an example view which receives an image file from the user |
| 271 | and saves a thumbnail of this image to a file named ``[userid].jpg``:: |
| 272 | |
| 273 | from django.contrib.thumbnails import Thumbnail, crop, ThumbnailException |
| 274 | |
| 275 | class ProfileThumbnail(Thumbnail): |
| 276 | size = (100, 100) |
| 277 | method = crop |
| 278 | |
| 279 | def profile_image(request, id): |
| 280 | profile = get_object_or_404(Profile, pk=id) |
| 281 | if request.method == 'POST': |
| 282 | image = request.FILES.get('profile_image') |
| 283 | profile.has_image = False |
| 284 | if image: |
| 285 | filename = str(profile.id) |
| 286 | try: |
| 287 | thumbnail = ProfileThumbnail(filename, image['content']) |
| 288 | profile.has_image = True |
| 289 | except ThumbnailException: |
| 290 | pass |
| 291 | profile.save() |
| 292 | return HttpResponseRedirect('../') |
| 293 | ... |