Сталкивался с такой задачей. Писал декоратор для метода сохранения модели:
def crop_and_resize(crop_fields=('image',),
resize_to=(800, 600),
crop_to=(188, 190)):
def _crop_and_resize(func):
def wrapper(obj, *a, **kw):
output = func(obj, *a, **kw)
for field in obj._meta.fields:
if isinstance(field, ImageField):
try:
path = getattr(getattr(obj, field.name), 'path')
img = Image.open(path)
if hasattr(obj, field.name+'_xywh') \
and field.name in crop_fields:
x, y, w, h = (
int(x) for x in getattr(obj, field.name+'_xywh').split(';'))
img = img.crop((x, y, x+w, y+h))
if img.size > crop_to:
img = img.resize(crop_to, Image.ANTIALIAS)
img.save(path+'_thumb.jpg', format='JPEG', quality=100)
else:
if img.size > resize_to:
img.thumbnail(resize_to, Image.ANTIALIAS)
img.save(path, format='JPEG', quality=100)
except: pass
return output
return wrapper
return _crop_and_resize
Только нужно в форме создать поля для передачи координат обрезки и передавать их в метод сохранения модели. Ну, понятно что координаты должны задаваться джаваскриптом.