Skip to content

Commit

Permalink
process() accepts file
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
matthewwithanm committed Sep 22, 2011
1 parent bd7eb72 commit 0ef56e1
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 13 deletions.
10 changes: 5 additions & 5 deletions imagekit/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def __init__(self, processors=None, quality=70, format=None):
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
Expand Down Expand Up @@ -161,7 +161,7 @@ def _create(self):
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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down
16 changes: 8 additions & 8 deletions imagekit/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class method named "process" which processes the supplied image using
class ImageProcessor(object):
""" Base image processor class """

def process(self, img, fmt, obj, spec):
def process(self, img, fmt, file):
return img, fmt


Expand All @@ -23,7 +23,7 @@ def __init__(self, color=1.0, brightness=1.0, contrast=1.0, sharpness=1.0):
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())
Expand All @@ -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
Expand Down Expand Up @@ -88,7 +88,7 @@ def __init__(self, width=None, height=None):
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.')


Expand Down Expand Up @@ -120,7 +120,7 @@ def __init__(self, width=None, height=None, anchor=None):
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]
Expand Down Expand Up @@ -148,7 +148,7 @@ def __init__(self, width=None, height=None, upscale=None):
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,
Expand Down Expand Up @@ -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 = []
Expand Down

0 comments on commit 0ef56e1

Please sign in to comment.