mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-03-17 05:40:25 +00:00
Processors are now instance-based.
This commit is contained in:
parent
a9895f335a
commit
cd3395b68f
2 changed files with 50 additions and 55 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue