Django Daguerre¶
Django Daguerre manipulates images on the fly. Use it to scale images up or down. Use it to generate thumbnails in bulk or sets of responsive images without slowing down your templates. Or customize it to do even more powerful image processing.
You don’t need to run a cron job ahead of time. You don’t need to make any changes to your models. It just works.
{% load daguerre %}
<img src="{% adjust my_model.image "fill" width=200 height=400 %}" />
{% adjust_bulk my_queryset "method.image" "fill" width=200 height=400 as adjusted_list %}
{% for my_model, image in adjusted_list %}
<img src="{{ image }}" />
{% endfor %}
Code: | http://github.com/littleweaver/django-daguerre |
---|---|
Docs: | http://readthedocs.org/docs/django-daguerre/ |
Build status: |
Contents¶
Installation and Setup¶
Installation¶
Install the latest version of Daguerre using pip
:
pip install django-daguerre
You can also clone the repository or download a package at https://github.com/littleweaver/django-daguerre.
Setup¶
Add 'daguerre'
to your project’s INSTALLED_APPS
:
INSTALLED_APPS = (
'daguerre',
...
)
Add Daguerre’s URL patterns to your URLconf:
urlpatterns = patterns('',
url(r'^daguerre/', include('daguerre.urls')),
...
)
Now you’re ready to use Daguerre’s template tags!
Versions and Requirements¶
- Python 2.7+, 3.3+
- Pillow 2.7.0
- Django 1.7 & 1.8
- Six 1.10.0+
Daguerre may work with earlier versions of these packages, but they are not officially supported.
If you need to use earlier versions of Python or Django, refer this versions table to determine which version of Daguerre to install.
Package | Python | Django |
---|---|---|
Daguerre 2.1.0 | Python 2.7+, 3.3+ | Django 1.7+ |
Daguerre 2.0.0 | Python 2.6+, 3.3+ | Django 1.6.1+ |
Daguerre 1.0.1 | Python 2.6+ | Django 1.4+ |
You can install older versions of Daguerre with pip. E.g.,
pip install django-daguerre==2.0
Template Tags¶
adjust¶
The easiest way to use Daguerre is through the {% adjust %}
template tag:
{% load daguerre %}
<img src="{% adjust my_model.image 'fill' width=128 height=256 %}" />
The {% adjust %}
tag works directly with any ImageField (or storage path).
There is no magic. You don’t need to change your models. It Just Works.
Daguerre provides a number of built-in adjustments (such as ‘fill’) which
can be used with the {% adjust %}
out of the box, as well as an
API for registering custom adjustments.
Take this picture:
Let’s use {% adjust %}
with width 200 (25%) and height 300
(50%), with three of the built-in adjustments.
“fit” | “fill” | “crop” |
---|---|---|
Fits the entire image into the given dimensions without distorting it. | Fills the entire space given by the dimensions by cropping to the same width/height ratio and then scaling down or up. | Crops the image to the given dimensions without any resizing. |
Chaining Adjustments¶
You can also use the {% adjust %}
tag to chain multiple
adjustments. Take the following:
{% load daguerre %}
{% adjust my_model.image 'ratiocrop' ratio='16:9' 'fit' width=200 %}
This tag first crops the image to a 16:9 ratio, then scales as much as needed to fit within a 200-pixel width. In other words:
See also
daguerre.adjustments
for more built-in adjustments.
Getting adjusted width and height¶
{% load daguerre %}
{% adjust my_model.image 'fit' width=128 height=128 as image %}
<img src="{{ image }}" width="{{ image.width }}" height="{{ image.height }}" />
The object being set to the image
context variable is an
AdjustmentInfoDict
instance. In addition to rendering as
the URL for an image, this object provides access to some other
useful pieces of information—in particular, the width and height
that the adjusted image will have, based on the width and height
of the original image and the parameters given to the tag. This can
help you avoid changes to page flow as adjusted images load.
Let’s be lazy¶
So the {% adjust %}
tag renders as a URL to adjusted image,
right? Yes, but as lazily as possible. If the adjustment has already
been performed, the adjusted image’s URL is fetched from the database.
If the adjustment has not been performed, the tag renders as a URL
to a view which, when accessed, will create an adjusted version of the
image and return a redirect to the adjusted image’s actual URL.
This does have the downside of requiring an additional
request/response cycle when unadjusted images are fetched by the user
– but it has the upside that no matter how many {% adjust %}
tags you have on a page, the initial load of the page won’t be slowed
down by (potentially numerous, potentially expensive) image
adjustments.
Note
The adjustment view has some light security in place to make sure that users can’t run arbitrary image resizes on your servers.
adjust_bulk¶
If you are using a large number of similar adjustments in one
template - say, looping over a queryset and adjusting the same
attribute each time - you can save yourself queries by using
{% adjust_bulk %}
.
{% load daguerre %}
{% adjust_bulk my_queryset "method.image" "fill" width=200 height=400 as adjusted_list %}
{% for my_model, image in adjusted_list %}
<img src="{{ image }}" />
{% endfor %}
The syntax is similar to {% adjust %}
, except that:
as <varname>
is required.- an iterable (
my_queryset
) and a lookup to be performed on each item in the iterable ("method.image"
) are provided in place of an image file or storage path. (If the iterable is an iterable of image files or storage paths, the lookup is not required.)
You’ve got everything you need now to use Daguerre and resize images like a champ. But what if you need more control over how your images are cropped? Read on to learn about Smart Cropping with Areas.
Smart Cropping with Areas¶
Daguerre allows you to influence how images are cropped with
Areas
.
Use the AreaWidget¶
Daguerre provides a widget which can be used with any
ImageField
to edit Areas
for that image file.
Add this formfield override to your ModelAdmin to enable the widget.
from daguerre.widgets import AreaWidget
class YourModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.ImageField: {'widget': AreaWidget},
}
...
Adjustments with Areas¶
After you define Areas
for an image in the admin,
adjustments that remove parts of the image (such as crop) will protect
those parts of the image during processing. See the difference in this
adjustment.
<img src="{% adjust my_model.image "fill" width=600 height=200 %}" />
Result without ‘face’ Area defined |
---|
Result with ‘face’ Area defined |
---|
Areas and namedcrop¶
You can also use the built-in “namedcrop” adjustment force a specific crop.
<img src="{% adjust my_model.image "namedcrop" name="face" %}" />
Management Commands¶
./manage.py daguerre clean
¶
Cleans out extra or invalid data stored by daguerre:
AdjustedImages
andAreas
that reference storage paths which no longer exist.- Duplicate
AdjustedImages
. - Adjusted image files which don’t have an associated
AdjustedImage
. AdjustedImage
instances with missing adjusted image files.
./manage.py daguerre preadjust [--remove] [--nocreate]
¶
Looks for a DAGUERRE_PREADJUSTMENTS
setting using the following
structure:
from daguerre.adjustments import Fit, Fill
DAGUERRE_PREADJUSTMENTS = (
('myapp.MyModel',
[Fit(width=800, height=500)],
'template.style.lookup'),
(OtherModel.objects.filter(field=value),
[Fill(width=300, height=216)].
'template.style.lookup'),
...
)
Essentially, this is expected to be an iterable of tuples, where each tuple contains three items:
'<applabel>.<model>'
, a model class, a queryset, or any iterable.- A non-empty iterable of adjustment instances to be applied to each image.
- A template-style lookup (or None).
Each time the command is run, the first item will be used to generate a
fresh iterable of model instances. The lookup will be applied to each
instance to get an ImageFile
or storage path, which will then have
the list of adjustments applied it to create a new adjusted version of
the image, if one doesn’t exist already. (This is essentially the same
functionality as the {% adjust_bulk %}
template tag.)
If --remove
is specified, the command will delete all
AdjustedImage
instances which would not be generated by the
parameters specified in DAGUERRE_PREADJUSTMENTS
.
If --nocreate
is specified, the command will not create any new
AdjustedImage
instances. This can be used with --remove
to just prune instances that aren’t specified in
DAGUERRE_PREADJUSTMENTS
without creating new pre-adjusted instances.
Specifying --nocreate
without --remove
makes this command a
no-op.
API Docs¶
Adjustments¶
Daguerre provides a variety of adjustments to use when processing images, as well as an API for registering custom adjustments.
Built-In Adjustments¶
When used with the template tag, these adjustments should be referred to by their lowercase name:
{% adjust image "fit" width=300 %}
See Template Tags for examples.
Custom Adjustments¶
You can easily add custom adjustments for your particular project. For example, an adjustment to make an image grayscale might look something like this:
# Somewhere that will be imported.
from daguerre.adjustments import Adjustment, registry
from PIL import ImageOps
@registry.register
class GrayScale(Adjustment):
def adjust(self, image, areas=None):
return ImageOps.grayscale(image)
adjust.uses_areas = False
Now you can use your adjustment in templates:
{% adjust image "grayscale" %}
Models¶
Release Notes¶
Release Notes¶
2.2.0 (2016-04-13)¶
- Improved efficiency of adjusted image queries (thanks @mislavcimpersak!)
- Fixed some minor image adjustment bugs.
- Added Jinja template support.
- Added compatibility with Django 1.8