-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 992dd85
Showing
14 changed files
with
1,038 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Copyright (c) 2009, Chris Beaven | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, | ||
this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
* Neither the name easy-thumbnails nor the names of its contributors may be | ||
used to endorse or promote products derived from this software without | ||
specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
=============== | ||
Easy Thumbnails | ||
=============== | ||
|
||
The powerful, yet easy to implement thumbnailing application for Django. | ||
|
||
To install this application into your project, just add it to your | ||
``INSTALLED_APPS`` setting:: | ||
|
||
INSTALLED_APPS = ( | ||
... | ||
'easy_thumbnails', | ||
) | ||
|
||
|
||
Template usage | ||
============== | ||
|
||
To generate thumbnails in your template, use the ``{% thumbnail %}`` tag. To | ||
make this tag available for use in your template, use:: | ||
|
||
{% load thumbnails %} | ||
|
||
Basic tag Syntax:: | ||
|
||
{% thumbnail [source] [size] [options] %} | ||
|
||
*source* must be a ``File`` object, usually an Image/FileField of a model | ||
instance. | ||
|
||
*size* can either be: | ||
|
||
* the size in the format ``[width]x[height]`` (for example, | ||
``{% thumbnail person.photo 100x50 %}``) or | ||
|
||
* a variable containing a valid size (i.e. either a string in the | ||
``[width]x[height]`` format or a tuple containing two integers): | ||
``{% thumbnail person.photo size_var %}``. | ||
|
||
*options* are a space separated list of options which are used when processing | ||
the image to a thumbnail such as ``sharpen``, ``crop`` and ``quality=90``. | ||
|
||
|
||
Model usage | ||
=========== | ||
|
||
You can use the ``ThumbnailerField`` or ``ThumbnailerImageField`` fields (based | ||
on ``FileField`` and ``ImageField``, respectively) for easier access to | ||
retrieve (or generate) thumbnail images. | ||
|
||
Lower level usage | ||
================= | ||
|
||
Thumbnails are generated with a ``Thumbnailer`` instance. For example:: | ||
|
||
from easy_thumbnails import Thumbnailer | ||
|
||
def square_thumbnail(source): | ||
thumbnail_options = dict(size=(100, 100), crop=True, bw=True) | ||
return Thumbnailer(source).get_thumbnail(thumbnail_options) | ||
|
||
By default, ``get_thumbnail`` saves the file (using file storage). The source | ||
file used to instanciate the ``Thumbnailer`` must have a ``name`` instance | ||
relative to the storage root. | ||
|
||
The ``ThumbnailFile`` object provided makes this easy:: | ||
|
||
from easy_thumbnails import ThumbnailFile | ||
|
||
# For an existing file in storage: | ||
source = ThumbnailFile('animals/aarvark.jpg') | ||
square_thumbnail(source) | ||
|
||
# For a new file: | ||
picture = open('/home/zookeeper/pictures/my_anteater.jpg') | ||
source = ThumbnailFile('animals/anteater.jpg', file=picture) | ||
square_thumbnail(source) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from files import Thumbnailer, ThumbnailFile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
DEBUG = False | ||
|
||
DEFAULT_STORAGE = 'easy_thumbnails.storage.ThumbnailFileSystemStorage' | ||
MEDIA_ROOT = '' | ||
MEDIA_URL = '' | ||
|
||
BASEDIR = '' | ||
SUBDIR = '' | ||
PREFIX = '' | ||
|
||
QUALITY = 85 | ||
EXTENSION = 'jpg' | ||
PROCESSORS = ( | ||
'easy_thumbnails.processors.colorspace', | ||
'easy_thumbnails.processors.autocrop', | ||
'easy_thumbnails.processors.scale_and_crop', | ||
'easy_thumbnails.processors.filters', | ||
) | ||
IMAGEMAGICK_FILE_TYPES = ('eps', 'pdf', 'psd') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from easy_thumbnails import defaults, utils | ||
from django.core.files.base import ContentFile | ||
import os | ||
try: | ||
from cStringIO import StringIO | ||
except ImportError: | ||
from StringIO import StringIO | ||
|
||
|
||
DEFAULT_PROCESSORS = [utils.dynamic_import(p) | ||
for p in utils.get_setting('PROCESSORS')] | ||
|
||
|
||
def process_image(source, processor_options, processors=None): | ||
""" | ||
Process a source PIL image through a series of image processors, returning | ||
the (potentially) altered image. | ||
""" | ||
if processors is None: | ||
processors = DEFAULT_PROCESSORS | ||
image = source | ||
for processor in processors: | ||
image = processor(image, **processor_options) | ||
return image | ||
|
||
|
||
def save_image(image, destination=None, format='JPEG', quality=85): | ||
""" | ||
Save a PIL image. | ||
""" | ||
if destination is None: | ||
destination = StringIO() | ||
try: | ||
image.save(destination, format=format, quality=quality, optimize=1) | ||
except IOError: | ||
# Try again, without optimization (PIL can't optimize an image | ||
# larger than ImageFile.MAXBLOCK, which is 64k by default) | ||
image.save(destination, format=format, quality=quality) | ||
if hasattr(destination, 'seek'): | ||
destination.seek(0) | ||
return destination | ||
|
||
|
||
def get_filetype(filename, is_path=False): | ||
""" | ||
Return the standardized extension based on the ``filename``. | ||
If ``is_path`` is True, try using imagemagick to determine the file type | ||
rather than just relying on the filename extension. | ||
""" | ||
if is_path: | ||
filetype = get_filetype_magic(filename) | ||
if not is_path or not filetype: | ||
filetype = os.path.splitext(filename)[1].lower()[:1] | ||
if filetype == 'jpeg': | ||
filetype = 'jpg' | ||
return filetype | ||
|
||
|
||
def get_filetype_magic(path): | ||
""" | ||
Return a standardized extention by using imagemagick (or ``None`` if | ||
imagemagick can not be imported). | ||
""" | ||
try: | ||
import magic | ||
except ImportError: | ||
return None | ||
|
||
m = magic.open(magic.MAGIC_NONE) | ||
m.load() | ||
filetype = m.file(path) | ||
if filetype.find('Microsoft Office Document') != -1: | ||
return 'doc' | ||
elif filetype.find('PDF document') != -1: | ||
return 'pdf' | ||
elif filetype.find('JPEG') != -1: | ||
return 'jpg' | ||
return filetype |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from django.db.models.fields.files import FileField, ImageField | ||
from easy_thumbnails import files | ||
|
||
|
||
class ThumbnailerField(FileField): | ||
""" | ||
A file field which provides easier access for retrieving (and generating) | ||
thumbnails. | ||
To use a different file storage for thumbnails, provide the | ||
``thumbnail_storage`` keyword argument. | ||
""" | ||
attr_class = files.ThumbnailerFieldFile | ||
|
||
def __init__(self, *args, **kwargs): | ||
# Arguments not explicitly defined so that the normal ImageField | ||
# positional arguments can be used. | ||
self.thumbnail_storage = kwargs.pop('thumbnail_storage', None) | ||
|
||
super(ThumbnailerField, self).__init__(*args, **kwargs) | ||
|
||
def south_field_triple(self): | ||
""" | ||
Return a suitable description of this field for South. | ||
""" | ||
from south.modelsinspector import introspector | ||
field_class = 'django.db.models.fields.files.FileField' | ||
args, kwargs = introspector(FileField) | ||
return (field_class, args, kwargs) | ||
|
||
|
||
class ThumbnailerImageField(ThumbnailerField, ImageField): | ||
""" | ||
An image field which provides easier access for retrieving (and generating) | ||
thumbnails. | ||
To use a different file storage for thumbnails, provide the | ||
``thumbnail_storage`` keyword argument. | ||
To thumbnail the original source image before saving, provide the | ||
``resize_source`` keyword argument, passing it a usual thumbnail option | ||
dictionary. For example:: | ||
ThumbnailField(..., resize_source=dict(size=(100, 100), sharpen=True)) | ||
""" | ||
attr_class = files.ThumbnailerImageFieldFile | ||
|
||
def __init__(self, *args, **kwargs): | ||
# Arguments not explicitly defined so that the normal ImageField | ||
# positional arguments can be used. | ||
self.resize_source = kwargs.pop('resize_source', None) | ||
|
||
super(ThumbnailerImageField, self).__init__(*args, **kwargs) | ||
|
||
def south_field_triple(self): | ||
""" | ||
Return a suitable description of this field for South. | ||
""" | ||
from south.modelsinspector import introspector | ||
field_class = 'django.db.models.fields.files.ImageField' | ||
args, kwargs = introspector(ImageField) | ||
return (field_class, args, kwargs) |
Oops, something went wrong.