diff --git a/imagekit/processors.py b/imagekit/processors.py index 4988f60..0ea7efa 100644 --- a/imagekit/processors.py +++ b/imagekit/processors.py @@ -11,22 +11,22 @@ from imagekit.lib import * 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) @@ -39,9 +39,8 @@ 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): @@ -49,10 +48,9 @@ class Reflection(ImageProcessor): 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 @@ -60,8 +58,8 @@ class Reflection(ImageProcessor): # 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): @@ -74,7 +72,7 @@ class Reflection(ImageProcessor): # 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) @@ -88,47 +86,48 @@ class Reflection(ImageProcessor): class Resize(ImageProcessor): - width = None - height = None - crop = False - upscale = False + + def __init__(self, width, height, crop=False, upscale=False): + self.width = width + self.height = height + self.crop = crop + self.upscale = upscale - @classmethod - def process(cls, img, fmt, obj): + 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 @@ -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 diff --git a/imagekit/specs.py b/imagekit/specs.py index cc6fc86..905639b 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -14,20 +14,17 @@ from django.core.files.base import ContentFile 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 @@ -84,7 +81,7 @@ class Accessor(object): 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,