Merge pull request #68 from matthewwithanm/options-arg

Replaces `quality` argument with `options` dict
This commit is contained in:
Chris Drackett 2011-11-16 08:36:37 -08:00
commit b89bc96e4b
4 changed files with 33 additions and 25 deletions

View file

@ -23,7 +23,7 @@ of a model class::
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
formatted_image = ImageSpec(image_field='original_image', format='JPEG',
quality=90)
options={'quality': 90})
Accessing the spec through a model instance will create the image and return
an ImageFile-like object (just like with a normal
@ -51,7 +51,7 @@ your spec, you can expose different versions of the original image::
original_image = models.ImageField(upload_to='photos')
thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
resize.Crop(50, 50)], image_field='original_image',
format='JPEG', quality=90)
format='JPEG', options={'quality': 90})
The ``thumbnail`` property will now return a cropped image::
@ -77,7 +77,7 @@ implement a ``process()`` method::
class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
watermarked_image = ImageSpec([Watermark()], image_field='original_image',
format='JPEG', quality=90)
format='JPEG', options={'quality': 90})
Admin

View file

@ -15,11 +15,11 @@ from imagekit.processors import ProcessorPipeline, AutoConvert
class _ImageSpecMixin(object):
def __init__(self, processors=None, quality=70, format=None,
def __init__(self, processors=None, format=None, options={},
autoconvert=True):
self.processors = processors
self.quality = quality
self.format = format
self.options = options
self.autoconvert = autoconvert
def process(self, image, file):
@ -35,16 +35,19 @@ class ImageSpec(_ImageSpecMixin):
"""
_upload_to_attr = 'cache_to'
def __init__(self, processors=None, quality=70, format=None,
def __init__(self, processors=None, format=None, options={},
image_field=None, pre_cache=False, storage=None, cache_to=None,
autoconvert=True):
"""
:param processors: A list of processors to run on the original image.
:param quality: The quality of the output image. This option is only
used for the JPEG format.
:param format: The format of the output file. If not provided,
ImageSpec will try to guess the appropriate format based on the
extension of the filename and the format of the input image.
:param options: A dictionary that will be passed to PIL's
``Image.save()`` method as keyword arguments. Valid options vary
between formats, but some examples include ``quality``,
``optimize``, and ``progressive`` for JPEGs. See the PIL
documentation for others.
:param image_field: The name of the model property that contains the
original image.
:param pre_cache: A boolean that specifies whether the image should
@ -71,8 +74,8 @@ class ImageSpec(_ImageSpecMixin):
"""
_ImageSpecMixin.__init__(self, processors, quality=quality,
format=format, autoconvert=autoconvert)
_ImageSpecMixin.__init__(self, processors, format=format,
options=options, autoconvert=autoconvert)
self.image_field = image_field
self.pre_cache = pre_cache
self.storage = storage
@ -125,6 +128,7 @@ class _ImageSpecFileMixin(object):
img = open_image(content)
original_format = img.format
img = self.field.process(img, self)
options = dict(self.field.options or {})
# Determine the format.
format = self.field.format
@ -139,19 +143,14 @@ class _ImageSpecFileMixin(object):
pass
format = format or img.format or original_format or 'JPEG'
if format == 'JPEG':
img_to_fobj_kwargs = dict(quality=int(self.field.quality),
optimize=True)
else:
img_to_fobj_kwargs = {}
# Run the AutoConvert processor
if getattr(self.field, 'autoconvert', True):
autoconvert_processor = AutoConvert(format)
img = autoconvert_processor.process(img)
img_to_fobj_kwargs.update(autoconvert_processor.save_kwargs)
options = dict(autoconvert_processor.save_kwargs.items() + \
options.items())
imgfile = img_to_fobj(img, format, **img_to_fobj_kwargs)
imgfile = img_to_fobj(img, format, **options)
content = ContentFile(imgfile.read())
return img, content
@ -358,18 +357,22 @@ class ProcessedImageField(models.ImageField, _ImageSpecMixin):
_upload_to_attr = 'upload_to'
attr_class = ProcessedImageFieldFile
def __init__(self, processors=None, quality=70, format=None,
def __init__(self, processors=None, format=None, options={},
verbose_name=None, name=None, width_field=None, height_field=None,
autoconvert=True, **kwargs):
"""
The ProcessedImageField constructor accepts all of the arguments that
the :class:`django.db.models.ImageField` constructor accepts, as well
as the ``processors``, ``format``, and ``quality`` arguments of
as the ``processors``, ``format``, and ``options`` arguments of
:class:`imagekit.models.ImageSpec`.
"""
_ImageSpecMixin.__init__(self, processors, quality=quality,
format=format, autoconvert=autoconvert)
if 'quality' in kwargs:
raise Exception('The "quality" keyword argument has been'
""" deprecated. Use `options={'quality': %s}` instead.""" \
% kwargs['quality'])
_ImageSpecMixin.__init__(self, processors, format=format,
options=options, autoconvert=autoconvert)
models.ImageField.__init__(self, verbose_name, name, width_field,
height_field, **kwargs)

View file

@ -187,10 +187,10 @@ class AutoConvert(object):
def __init__(self, format):
self.format = format
self.save_kwargs = {}
def process(self, img):
matte = False
self.save_kwargs = {}
if img.mode == 'RGBA':
if self.format in RGBA_TRANSPARENCY_FORMATS:
pass
@ -250,4 +250,7 @@ class AutoConvert(object):
bg.paste(img, img)
img = bg.convert('RGB')
if self.format == 'JPEG':
self.save_kwargs['optimize'] = True
return img

View file

@ -16,10 +16,12 @@ class Photo(models.Model):
original_image = models.ImageField(upload_to='photos')
thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1), Crop(50, 50)],
image_field='original_image', format='JPEG', quality=90)
image_field='original_image', format='JPEG',
options={'quality': 90})
smartcropped_thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1), SmartCrop(50, 50)],
image_field='original_image', format='JPEG', quality=90)
image_field='original_image', format='JPEG',
options={'quality': 90})
class IKTest(TestCase):