mirror of
https://github.com/Hopiu/django-imagekit.git
synced 2026-04-20 21:20:58 +00:00
Implemented configurable crop fields
This commit is contained in:
parent
8e51a21975
commit
bc8c44acff
6 changed files with 28 additions and 33 deletions
|
|
@ -1,11 +1,12 @@
|
|||
""" Default ImageKit configuration """
|
||||
|
||||
from imagekit.specs import ImageSpec
|
||||
from imagekit import processors
|
||||
|
||||
|
||||
class ResizeThumbnail(processors.Resize):
|
||||
width = 100
|
||||
height = 75
|
||||
crop = ('center', 'center')
|
||||
height = 50
|
||||
crop = True
|
||||
|
||||
class EnhanceSmall(processors.Adjustment):
|
||||
contrast = 1.2
|
||||
|
|
|
|||
|
|
@ -11,14 +11,11 @@ from imagekit import specs
|
|||
|
||||
class IKModelBase(ModelBase):
|
||||
def __init__(cls, name, bases, attrs):
|
||||
|
||||
parents = [b for b in bases if isinstance(b, IKModelBase)]
|
||||
if not parents:
|
||||
return
|
||||
|
||||
user_opts = getattr(cls, 'IKConfig', None)
|
||||
opts = Options(user_opts)
|
||||
|
||||
try:
|
||||
module = __import__(opts.config_module, {}, {}, [''])
|
||||
except ImportError:
|
||||
|
|
@ -30,7 +27,6 @@ class IKModelBase(ModelBase):
|
|||
and spec != specs.ImageSpec]:
|
||||
setattr(cls, spec.name(), specs.Descriptor(spec))
|
||||
opts.specs.append(spec)
|
||||
|
||||
setattr(cls, '_ik', opts)
|
||||
|
||||
|
||||
|
|
@ -59,25 +55,18 @@ class IKModel(models.Model):
|
|||
(self.get_absolute_url(), prop.url)
|
||||
else:
|
||||
return u'<a href="%s"><img src="%s"></a>' % \
|
||||
(self.ik_image_field.url, prop.url)
|
||||
(self._imgfield.url, prop.url)
|
||||
admin_thumbnail_view.short_description = _('Thumbnail')
|
||||
admin_thumbnail_view.allow_tags = True
|
||||
|
||||
@property
|
||||
def _imgfield(self):
|
||||
return getattr(self, self._ik.image_field)
|
||||
|
||||
def _cleanup_cache_dirs(self):
|
||||
try:
|
||||
os.removedirs(self.cache_path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def _clear_cache(self):
|
||||
for spec in self._ik.specs:
|
||||
prop = getattr(self, spec.name())
|
||||
prop._delete()
|
||||
self._cleanup_cache_dirs()
|
||||
|
||||
def _pre_cache(self):
|
||||
for spec in self._ik.specs:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ class Options(object):
|
|||
|
||||
"""
|
||||
image_field = 'image'
|
||||
crop_horz_field = 'crop_horz'
|
||||
crop_vert_field = 'crop_vert'
|
||||
max_image_size = None
|
||||
cache_dir = 'images'
|
||||
save_count_as = None
|
||||
|
|
|
|||
|
|
@ -11,34 +11,36 @@ from imagekit import *
|
|||
class ImageProcessor(object):
|
||||
""" Base image processor class """
|
||||
@classmethod
|
||||
def process(cls, image):
|
||||
def process(cls, image, obj):
|
||||
return image
|
||||
|
||||
|
||||
class Resize(ImageProcessor):
|
||||
width = None
|
||||
height = None
|
||||
crop = False # ('top', 'left')
|
||||
crop = False
|
||||
upscale = False
|
||||
|
||||
@classmethod
|
||||
def process(cls, image):
|
||||
def process(cls, image, obj):
|
||||
cur_width, cur_height = image.size
|
||||
if cls.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)
|
||||
resize_x, resize_y = ((cur_width * ratio), (cur_height * ratio))
|
||||
crop_x, crop_y = (abs(cls.width - resize_x), abs(cls.height - resize_y))
|
||||
x_diff, y_diff = (int(crop_x / 2), int(crop_y / 2))
|
||||
box_upper, box_lower = {
|
||||
'top': (9, cls.height),
|
||||
'center': (int(y_diff), int(y_diff + cls.height)),
|
||||
'bottom': (int(crop_y), int(resize_y)),
|
||||
}[cls.crop[0]]
|
||||
box_left, box_right = {
|
||||
'left': (0, cls.width),
|
||||
'center': (int(x_diff), int(x_diff +cls.width)),
|
||||
'right': (int(crop_x), int(resize_x)),
|
||||
}[cls.crop[1]]
|
||||
0: (0, cls.width),
|
||||
1: (int(x_diff), int(x_diff + cls.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)),
|
||||
2: (int(crop_y), int(resize_y)),
|
||||
}[crop_vert]
|
||||
box = (box_left, box_upper, box_right, box_lower)
|
||||
image = image.resize((int(resize_x), int(resize_y)), Image.ANTIALIAS).crop(box)
|
||||
else:
|
||||
|
|
@ -74,7 +76,7 @@ class Transpose(ImageProcessor):
|
|||
method = 'FLIP_LEFT_RIGHT'
|
||||
|
||||
@classmethod
|
||||
def process(cls, image):
|
||||
def process(cls, image, obj):
|
||||
return image.transpose(getattr(Image, cls.method))
|
||||
|
||||
|
||||
|
|
@ -85,7 +87,7 @@ class Adjustment(ImageProcessor):
|
|||
sharpness = 1.0
|
||||
|
||||
@classmethod
|
||||
def process(cls, image):
|
||||
def process(cls, image, obj):
|
||||
for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']:
|
||||
factor = getattr(cls, name.lower())
|
||||
if factor != 1.0:
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ class ImageSpec(object):
|
|||
return getattr(cls, 'access_as', cls.__name__.lower())
|
||||
|
||||
@classmethod
|
||||
def process(cls, image):
|
||||
def process(cls, image, obj):
|
||||
processed_image = image.copy()
|
||||
for proc in cls.processors:
|
||||
processed_image = proc.process(processed_image)
|
||||
processed_image = proc.process(processed_image, obj)
|
||||
return processed_image
|
||||
|
||||
|
||||
|
|
@ -38,7 +38,8 @@ class Accessor(object):
|
|||
if self._exists():
|
||||
return
|
||||
|
||||
self._img = self.spec.process(Image.open(self._obj._imgfield.path))
|
||||
self._img = self.spec.process(Image.open(self._obj._imgfield.path),
|
||||
self._obj)
|
||||
|
||||
fmt = self._img.format or 'JPEG'
|
||||
tmp = tempfile.TemporaryFile()
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class TestResizeCropped(ImageSpec):
|
|||
|
||||
class TestPhoto(IKModel):
|
||||
""" Minimal ImageModel class for testing """
|
||||
image = models.ImageField(upload_to='originals')
|
||||
image = models.ImageField(upload_to='images')
|
||||
|
||||
class IKConfig:
|
||||
config_module = 'imagekit.tests'
|
||||
|
|
|
|||
Loading…
Reference in a new issue