From 0ef56e1aaa4c6f925df6f387ef96c9e873aa1d46 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 22 Sep 2011 17:31:26 -0400 Subject: [PATCH] `process()` accepts file In the old IK API, processors (like `Transpose`) were able to access the file by inspecting the model instance (which carried an options object that specified the attribute name of the ImageField from which the file could be extracted). Since the new API allows for multiple ImageFields (and because IKOptions have been removed), it became necessary to provide more information. Initially, this was accomplished by passing the spec to `process()`, however with the addition of ProcessedImageField, it became clear the a cleaner solution was to pass only the field file (ImageSpecFile or ProcessedImageFieldFile). This keeps the ORM stuff (fields, etc.) out of the `ImageProcessor` API but (because field files, not just regular files, are passed) the average hacker can still have their processor make use of model information by accessing the model through the file's `instance` property. --- imagekit/fields.py | 10 +++++----- imagekit/processors.py | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imagekit/fields.py b/imagekit/fields.py index fdf9002..3d3949e 100755 --- a/imagekit/fields.py +++ b/imagekit/fields.py @@ -24,11 +24,11 @@ class _ImageSpecMixin(object): self.quality = quality self.format = format - def process(self, image, obj): + def process(self, image, file): fmt = image.format img = image.copy() for proc in self.processors: - img, fmt = proc.process(img, fmt, obj, self) + img, fmt = proc.process(img, fmt, file) format = self.format or fmt img.format = format return img, format @@ -161,7 +161,7 @@ class ImageSpecFile(object): return fp.seek(0) fp = StringIO(fp.read()) - self._img, self._fmt = self._spec.process(Image.open(fp), self._obj) + self._img, self._fmt = self._spec.process(Image.open(fp), self) # save the new image to the cache content = ContentFile(self._get_imgfile().read()) self.storage.save(self.name, content) @@ -270,7 +270,7 @@ def _post_save_handler(sender, instance=None, created=False, raw=False, **kwargs if imgfield: newfile = imgfield.storage.open(imgfield.name) img = Image.open(newfile) - img, format = spec_file._spec.process(img, instance) + img, format = spec_file._spec.process(img, spec_file) if format != 'JPEG': imgfile = img_to_fobj(img, format) else: @@ -347,7 +347,7 @@ class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): new_filename = self.field.generate_filename(self.instance, name) img = Image.open(content) - img, format = self.field.process(img, self.instance) + img, format = self.field.process(img, self) format = self._get_format(new_filename, format) if format != 'JPEG': imgfile = img_to_fobj(img, format) diff --git a/imagekit/processors.py b/imagekit/processors.py index 825f32e..028a884 100644 --- a/imagekit/processors.py +++ b/imagekit/processors.py @@ -11,7 +11,7 @@ from imagekit.lib import * class ImageProcessor(object): """ Base image processor class """ - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): return img, fmt @@ -23,7 +23,7 @@ class Adjust(ImageProcessor): self.contrast = contrast self.sharpness = sharpness - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): img = img.convert('RGB') for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']: factor = getattr(self, name.lower()) @@ -40,7 +40,7 @@ class Reflection(ImageProcessor): size = 0.0 opacity = 0.6 - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): # convert bgcolor string to rgb value background_color = ImageColor.getrgb(self.background_color) # handle palleted images @@ -88,7 +88,7 @@ class _Resize(ImageProcessor): if height is not None: self.height = height - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): raise NotImplementedError('process must be overridden by subclasses.') @@ -120,7 +120,7 @@ class Crop(_Resize): super(Crop, self).__init__(width, height) self.anchor = anchor - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): cur_width, cur_height = img.size horizontal_anchor, vertical_anchor = Crop._ANCHOR_PTS[self.anchor or \ Crop.CENTER] @@ -148,7 +148,7 @@ class Fit(_Resize): super(Fit, self).__init__(width, height) self.upscale = upscale - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): cur_width, cur_height = img.size if not self.width is None and not self.height is None: ratio = min(float(self.width)/cur_width, @@ -196,10 +196,10 @@ class Transpose(ImageProcessor): method = 'auto' - def process(self, img, fmt, obj, spec): + def process(self, img, fmt, file): if self.method == 'auto': try: - orientation = Image.open(spec._get_imgfield(obj).file)._getexif()[0x0112] + orientation = Image.open(file.file)._getexif()[0x0112] ops = self.EXIF_ORIENTATION_STEPS[orientation] except: ops = []