Skip to content

Commit

Permalink
Processors are now instance-based.
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewwithanm committed Sep 8, 2011
1 parent a9895f3 commit cd3395b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 56 deletions.
88 changes: 43 additions & 45 deletions imagekit/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ class method named "process" which processes the supplied image using
class ImageProcessor(object):
""" Base image processor class """

@classmethod
def process(cls, img, fmt, obj):
def process(self, img, fmt, obj):
return img, fmt


class Adjustment(ImageProcessor):
color = 1.0
brightness = 1.0
contrast = 1.0
sharpness = 1.0
class Adjust(ImageProcessor):

def __init__(self, color=1.0, brightness=1.0, contrast=1.0, sharpness=1.0):
self.color = color
self.brightness = brightness
self.contrast = contrast
self.sharpness = sharpness

@classmethod
def process(cls, img, fmt, obj):
def process(self, img, fmt, obj):
img = img.convert('RGB')
for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']:
factor = getattr(cls, name.lower())
factor = getattr(self, name.lower())
if factor != 1.0:
try:
img = getattr(ImageEnhance, name)(img).enhance(factor)
Expand All @@ -39,29 +39,27 @@ class Format(ImageProcessor):
format = 'JPEG'
extension = 'jpg'

@classmethod
def process(cls, img, fmt, obj):
return img, cls.format
def process(self, img, fmt, obj):
return img, self.format


class Reflection(ImageProcessor):
background_color = '#FFFFFF'
size = 0.0
opacity = 0.6

@classmethod
def process(cls, img, fmt, obj):
def process(self, img, fmt, obj):
# convert bgcolor string to rgb value
background_color = ImageColor.getrgb(cls.background_color)
background_color = ImageColor.getrgb(self.background_color)
# handle palleted images
img = img.convert('RGB')
# copy orignial image and flip the orientation
reflection = img.copy().transpose(Image.FLIP_TOP_BOTTOM)
# create a new image filled with the bgcolor the same size
background = Image.new("RGB", img.size, background_color)
# calculate our alpha mask
start = int(255 - (255 * cls.opacity)) # The start of our gradient
steps = int(255 * cls.size) # the number of intermedite values
start = int(255 - (255 * self.opacity)) # The start of our gradient
steps = int(255 * self.size) # the number of intermedite values
increment = (255 - start) / float(steps)
mask = Image.new('L', (1, 255))
for y in range(255):
Expand All @@ -74,7 +72,7 @@ def process(cls, img, fmt, obj):
# merge the reflection onto our background color using the alpha mask
reflection = Image.composite(background, reflection, alpha_mask)
# crop the reflection
reflection_height = int(img.size[1] * cls.size)
reflection_height = int(img.size[1] * self.size)
reflection = reflection.crop((0, 0, img.size[0], reflection_height))
# create new image sized to hold both the original image and the reflection
composite = Image.new("RGB", (img.size[0], img.size[1]+reflection_height), background_color)
Expand All @@ -88,47 +86,48 @@ def process(cls, img, fmt, obj):


class Resize(ImageProcessor):
width = None
height = None
crop = False
upscale = False

@classmethod
def process(cls, img, fmt, obj):

def __init__(self, width, height, crop=False, upscale=False):
self.width = width
self.height = height
self.crop = crop
self.upscale = upscale

def process(self, img, fmt, obj):
cur_width, cur_height = img.size
if cls.crop:
if self.crop:
crop_horz = getattr(obj, obj._ik.crop_horz_field, 1)
crop_vert = getattr(obj, obj._ik.crop_vert_field, 1)
ratio = max(float(cls.width)/cur_width, float(cls.height)/cur_height)
ratio = max(float(self.width)/cur_width, float(self.height)/cur_height)
resize_x, resize_y = ((cur_width * ratio), (cur_height * ratio))
crop_x, crop_y = (abs(cls.width - resize_x), abs(cls.height - resize_y))
crop_x, crop_y = (abs(self.width - resize_x), abs(self.height - resize_y))
x_diff, y_diff = (int(crop_x / 2), int(crop_y / 2))
box_left, box_right = {
0: (0, cls.width),
1: (int(x_diff), int(x_diff + cls.width)),
0: (0, self.width),
1: (int(x_diff), int(x_diff + self.width)),
2: (int(crop_x), int(resize_x)),
}[crop_horz]
box_upper, box_lower = {
0: (0, cls.height),
1: (int(y_diff), int(y_diff + cls.height)),
0: (0, self.height),
1: (int(y_diff), int(y_diff + self.height)),
2: (int(crop_y), int(resize_y)),
}[crop_vert]
box = (box_left, box_upper, box_right, box_lower)
img = img.resize((int(resize_x), int(resize_y)), Image.ANTIALIAS).crop(box)
else:
if not cls.width is None and not cls.height is None:
ratio = min(float(cls.width)/cur_width,
float(cls.height)/cur_height)
if not self.width is None and not self.height is None:
ratio = min(float(self.width)/cur_width,
float(self.height)/cur_height)
else:
if cls.width is None:
ratio = float(cls.height)/cur_height
if self.width is None:
ratio = float(self.height)/cur_height
else:
ratio = float(cls.width)/cur_width
ratio = float(self.width)/cur_width
new_dimensions = (int(round(cur_width*ratio)),
int(round(cur_height*ratio)))
if new_dimensions[0] > cur_width or \
new_dimensions[1] > cur_height:
if not cls.upscale:
if not self.upscale:
return img, fmt
img = img.resize(new_dimensions, Image.ANTIALIAS)
return img, fmt
Expand Down Expand Up @@ -162,16 +161,15 @@ class Transpose(ImageProcessor):

method = 'auto'

@classmethod
def process(cls, img, fmt, obj):
if cls.method == 'auto':
def process(self, img, fmt, obj):
if self.method == 'auto':
try:
orientation = Image.open(obj._imgfield.file)._getexif()[0x0112]
ops = cls.EXIF_ORIENTATION_STEPS[orientation]
ops = self.EXIF_ORIENTATION_STEPS[orientation]
except:
ops = []
else:
ops = [cls.method]
ops = [self.method]
for method in ops:
img = img.transpose(getattr(Image, method))
return img, fmt
19 changes: 8 additions & 11 deletions imagekit/specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@


class ImageSpec(object):
pre_cache = False
quality = 70
increment_count = False
processors = []

@classmethod
def name(cls):
return getattr(cls, 'access_as', cls.__name__.lower())
def __init__(self, processors, pre_cache=False, quality=70, increment_count=False):
self.processors = list(processors or [])
self.pre_cache = pre_cache
self.quality = quality
self.increment_count = increment_count

@classmethod
def process(cls, image, obj):
def process(self, image, obj):
fmt = image.format
img = image.copy()
for proc in cls.processors:
for proc in self.processors:
img, fmt = proc.process(img, fmt, obj)
img.format = fmt
return img, fmt
Expand Down Expand Up @@ -84,7 +81,7 @@ def name(self):
filepath, basename = os.path.split(self._obj._imgfield.name)
filename, extension = os.path.splitext(basename)
for processor in self.spec.processors:
if issubclass(processor, processors.Format):
if isinstance(processor, processors.Format):
extension = processor.extension
filename_format_dict = {'filename': filename,
'specname': self.property_name,
Expand Down

0 comments on commit cd3395b

Please sign in to comment.