def test_one_dimension_scale(self): image = create_image() scaled = processors.scale_and_crop(image, (100, 0)) self.assertEqual(scaled.size, (100, 75)) scaled = processors.scale_and_crop(image, (0, 100)) self.assertEqual(scaled.size, (133, 100))
def test_one_dimension_crop(self): image = create_image() cropped = processors.scale_and_crop(image, (100, 0), crop=True) self.assertEqual(cropped.size, (100, 75)) cropped = processors.scale_and_crop(image, (0, 100), crop=True) self.assertEqual(cropped.size, (133, 100))
def test_crop_target(self): image = create_image() # Try bottom right target. target = (95, 100) tl_crop = processors.scale_and_crop( image, size=(100, 600), crop=True, target=target) expected = image.crop([700, 0, 800, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop( image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 500, 800, 600]) self.assertImagesEqual(tl_crop, expected) # Top left target. target = (0, 5) tl_crop = processors.scale_and_crop( image, size=(100, 600), crop=True, target=target) expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop( image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 0, 800, 100]) self.assertImagesEqual(tl_crop, expected)
def test_crop_scale(self): image = create_image(size=(200, 400)) scaled = processors.scale_and_crop(image, (100, 100), crop='scale') self.assertEqual(scaled.size, (100, 200)) scaled = processors.scale_and_crop(image, (600, 600), crop='scale') self.assertEqual(scaled.size, (200, 400)) scaled = processors.scale_and_crop(image, (600, 600), crop='scale', upscale=True) self.assertEqual(scaled.size, (600, 1200))
def scale_and_crop_with_orientation( im, size, crop=False, upscale=False, **kwargs): ''' This processor change target size for portrait-oriented pictures ex: (800, 600) => (600, 800) ''' source_x, source_y = im.size if source_x < source_y: vertical_size = (size[1], size[0]) return scale_and_crop(im, vertical_size, crop, upscale, **kwargs) return scale_and_crop(im, size, crop, upscale, **kwargs)
def test_scale(self): image = create_image() scaled = processors.scale_and_crop(image, (100, 100)) self.assertEqual(scaled.size, (100, 75)) not_scaled = processors.scale_and_crop(image, (1000, 1000)) self.assertEqual(not_scaled.size, (800, 600)) upscaled = processors.scale_and_crop(image, (1000, 1000), upscale=True) self.assertEqual(upscaled.size, (1000, 750))
def test_crop_target_text(self): image = create_image() # Near centre target. target = '45,55' tl_crop = processors.scale_and_crop( image, size=(100, 600), crop=True, target=target) expected = image.crop([310, 0, 410, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop( image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 280, 800, 380]) self.assertImagesEqual(tl_crop, expected)
def _create_thumbnail(self, image, size): """Create a thumbnail for a given size This method creates thumbnail for the given width/height then saves them using field's storage. :param image: PIL source image :param size: width/height as a tuple """ if image.size != size: dest_image = scale_and_crop(image, size, crop='smart', upscale=True) else: dest_image = image dest_bytes = StringIO() if self.field.legacy_filenames: # Need to convert the file to a jpeg if dest_image.mode != "RGB": dest_image = dest_image.convert("RGB") dest_image.save(dest_bytes, format="JPEG") else: dest_image.save(dest_bytes, image.format) self.storage.save(self._get_thumbnail_name(size), ContentFile(dest_bytes.getvalue()))
def test_crop(self): image = create_image() both_cropped = processors.scale_and_crop(image, (100, 100), crop=True) self.assertEqual(both_cropped.size, (100, 100)) not_cropped = processors.scale_and_crop(image, (1000, 1000), crop=True) self.assertEqual(not_cropped.size, (800, 600)) x_cropped = processors.scale_and_crop(image, (600, 600), crop=True) expected = image.crop([100, 0, 700, 600]) self.assertImagesEqual(x_cropped, expected) y_cropped = processors.scale_and_crop(image, (1000, 100), crop=True) expected = image.crop([0, 350, 800, 450]) self.assertImagesEqual(y_cropped, expected)
def resize_image(src, dst, size=None, remove_src=True, locally=False): """Resizes and image from src, to dst. Returns width and height. When locally is True, src and dst are assumed to reside on the local disk (not in the default storage). When dealing with local files it's up to you to ensure that all directories exist leading up to the dst filename. """ if src == dst: raise Exception("src and dst can't be the same: %s" % src) open_ = open if locally else storage.open delete = os.unlink if locally else storage.delete with open_(src, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') if size: im = processors.scale_and_crop(im, size) with open_(dst, 'wb') as fp: im.save(fp, 'png') if remove_src: delete(src) return im.size
def clean_photo(self): """Let's make sure things are right. Cribbed from zamboni. Thanks Dave Dash! TODO: this needs to go into celery - File IT bug for celery - Ensure files aren't InMemory files - See zamboni.apps.users.forms """ photo = self.cleaned_data['photo'] if not photo: return if photo.content_type not in ('image/png', 'image/jpeg'): raise forms.ValidationError( _('Images must be either PNG or JPG.')) if photo.size > settings.MAX_PHOTO_UPLOAD_SIZE: raise forms.ValidationError( _('Please use images smaller than %dMB.' % (settings.MAX_PHOTO_UPLOAD_SIZE / 1024 / 1024 - 1))) im = Image.open(photo) # Resize large images if any(d > 300 for d in im.size): im = processors.scale_and_crop(im, (300, 300), crop=True) fn = tempfile.mktemp(suffix='.jpg') f = open(fn, 'w') im.save(f, 'JPEG') f.close() photo.file = open(fn) return photo
def render(self, img): img = exif_orientation(img) img = colorspace(img) # img = autocrop(img) if self.poi[0] and self.poi[1]: source_x, source_y = [float(v) for v in img.size] target = [self.poi[0] / source_x, self.poi[1] / source_y] for i in range(2): if target[i] > 1.: target[i] = 100. else: target[i] *= 100 else: target = None img = scale_and_crop(img, self.size, crop=self.crop, upscale=self.upscale, zoom=self.zoom, target=target) # img = filters(img) # img = background(img) return img
def resize_image(source, destination, size=None, format='png'): """Resizes and image from src, to dst. Returns a tuple of new width and height, original width and height. When dealing with local files it's up to you to ensure that all directories exist leading up to the dst filename. """ if source == destination: raise Exception("source and destination can't be the same: %s" % source) with storage.open(source, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') original_size = im.size if size: im = processors.scale_and_crop(im, size) if format == 'png': with storage.open(destination, 'wb') as fp: # Save the image to PNG in destination file path. # Don't keep the ICC profile as it can mess up pngcrush badly # (mozilla/addons/issues/697). im.save(fp, 'png', icc_profile=None) pngcrush_image(destination) else: with storage.open(destination, 'wb') as fp: im = im.convert('RGB') im.save(fp, 'JPEG', quality=80) return (im.size, original_size)
def test_crop(self): image = create_image() both_cropped = processors.scale_and_crop(image, (100, 100), crop=True) self.assertEqual(both_cropped.size, (100, 100)) not_cropped = processors.scale_and_crop(image, (1000, 1000), crop=True) self.assertEqual(not_cropped.size, (800, 600)) x_cropped = processors.scale_and_crop(image, (600, 600), crop=True) expected = image.crop([100, 0, 700, 600]) self.assertImagesEqual(x_cropped, expected) y_cropped = processors.scale_and_crop(image, (1000, 100), crop=True) expected = image.crop([0, 250, 800, 350]) self.assertImagesEqual(y_cropped, expected)
def resize_image(src, dst, size): """Resizes and image from src, to dst.""" if src == dst: raise Exception("src and dst can't be the same: %s" % src) im = Image.open(src) im = processors.scale_and_crop(im, size) im.save(dst) os.remove(src)
def test_crop_target_text(self): image = create_image() # Near centre target. target = '45,55' tl_crop = processors.scale_and_crop(image, size=(100, 600), crop=True, target=target) expected = image.crop([310, 0, 410, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop(image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 280, 800, 380]) self.assertImagesEqual(tl_crop, expected)
def resize_icon(src, dest): """Resizes collection icons to 32x32""" try: im = Image.open(src) im = processors.scale_and_crop(im, (32, 32)) im.save(dest) os.remove(src) except Exception, e: log.error("Error saving collection icon: %s" % e)
def resize_photo(src, dst): """Resizes userpics to 200x200""" task_log.info('[1@None] Resizing photo: %s' % dst) try: im = Image.open(src) im = processors.scale_and_crop(im, (200, 200)) im.save(dst) os.remove(src) except Exception, e: task_log.error("Error saving userpic: %s" % e)
def test_crop_corner(self): image = create_image() tl_crop = processors.scale_and_crop(image, (100, 600), crop='0,0') expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(tl_crop, expected) br_crop = processors.scale_and_crop(image, (100, 600), crop='-0,-0') expected = image.crop([700, 0, 800, 600]) self.assertImagesEqual(br_crop, expected) x_offset_crop = processors.scale_and_crop( image, (150, 600), crop='10,-10') expected = image.crop([15, 0, 165, 600]) self.assertImagesEqual(x_offset_crop, expected) y_offset_crop = processors.scale_and_crop(image, (800, 150), crop='10,-10') expected = image.crop([0, 435, 800, 585]) self.assertImagesEqual(y_offset_crop, expected) only_x_crop = processors.scale_and_crop(image, (100, 600), crop='0,') expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(only_x_crop, expected) only_y_crop = processors.scale_and_crop(image, (800, 100), crop=',0') expected = image.crop([0, 0, 800, 100]) self.assertImagesEqual(only_y_crop, expected)
def test_crop_corner(self): image = create_image() tl_crop = processors.scale_and_crop(image, (100, 600), crop='0,0') expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(tl_crop, expected) br_crop = processors.scale_and_crop(image, (100, 600), crop='-0,-0') expected = image.crop([700, 0, 800, 600]) self.assertImagesEqual(br_crop, expected) x_offset_crop = processors.scale_and_crop(image, (150, 600), crop='10,-10') expected = image.crop([15, 0, 165, 600]) self.assertImagesEqual(x_offset_crop, expected) y_offset_crop = processors.scale_and_crop(image, (800, 150), crop='10,-10') expected = image.crop([0, 435, 800, 585]) self.assertImagesEqual(y_offset_crop, expected) only_x_crop = processors.scale_and_crop(image, (100, 600), crop='0,') expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(only_x_crop, expected) only_y_crop = processors.scale_and_crop(image, (800, 100), crop=',0') expected = image.crop([0, 0, 800, 100]) self.assertImagesEqual(only_y_crop, expected)
def resize_image(source, destination, size=None, *, format='png', quality=80): """Resizes and image from source, to destination. Returns a tuple of new width and height, original width and height. When dealing with local files it's up to you to ensure that all directories exist leading up to the destination filename. quality kwarg is only valid for jpeg format - it's ignored for png. """ if source == destination: raise Exception("source and destination can't be the same: %s" % source) source_fileext = os.path.splitext(source)[1] if source_fileext == '.svg': tmp_args = { 'dir': settings.TMP_PATH, 'mode': 'w+b', 'suffix': '.png', 'delete': not settings.DEBUG, } with tempfile.NamedTemporaryFile(**tmp_args) as temporary_png: convert_svg_to_png(source, temporary_png.name) im = Image.open(temporary_png.name) im.load() else: with storage.open(source, 'rb') as fp: im = Image.open(fp) im.load() original_size = im.size if size: im = processors.scale_and_crop(im.convert('RGBA'), size) with storage.open(destination, 'wb') as dest_file: if format == 'png': # Save the image to PNG in destination file path. # Don't keep the ICC profile as it can mess up pngcrush badly # (mozilla/addons/issues/697). im = im.convert('RGBA') im.save(dest_file, 'png', icc_profile=None) pngcrush_image(destination) else: if source_fileext == '.png': # Create a white rgba background for transparency white_background = Image.new('RGBA', im.size, 'WHITE') white_background.paste(im, (0, 0), im) im = white_background im = im.convert('RGB') im.save(dest_file, 'JPEG', quality=quality) new_size = im.size im.close() return (new_size, original_size)
def test_crop_target(self): image = create_image() # Try bottom right target. target = (95, 100) tl_crop = processors.scale_and_crop(image, size=(100, 600), crop=True, target=target) expected = image.crop([700, 0, 800, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop(image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 500, 800, 600]) self.assertImagesEqual(tl_crop, expected) # Top left target. target = (0, 5) tl_crop = processors.scale_and_crop(image, size=(100, 600), crop=True, target=target) expected = image.crop([0, 0, 100, 600]) self.assertImagesEqual(tl_crop, expected) tl_crop = processors.scale_and_crop(image, size=(800, 100), crop=True, target=target) expected = image.crop([0, 0, 800, 100]) self.assertImagesEqual(tl_crop, expected)
def resize_image(src, dst, size, remove_src=True): """Resizes and image from src, to dst.""" if src == dst: raise Exception("src and dst can't be the same: %s" % src) dirname = os.path.dirname(dst) if not os.path.exists(dirname): os.makedirs(dirname) im = Image.open(src) im = im.convert('RGBA') im = processors.scale_and_crop(im, size) im.save(dst, 'png') if remove_src: os.remove(src)
def resize_image(src, dst, size, remove_src=True): """Resizes and image from src, to dst. Returns width and height.""" if src == dst: raise Exception("src and dst can't be the same: %s" % src) with storage.open(src, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') im = processors.scale_and_crop(im, size) with storage.open(dst, 'wb') as fp: im.save(fp, 'png') if remove_src: storage.delete(src) return im.size
def _create_thumbnail(self, image, size): """Create a thumbnail for a given size This method creates thumbnail for the given width/height then saves them using field's storage. :param image: PIL source image :param size: width/height as a tuple """ dest_image = scale_and_crop(image, size, crop='smart', upscale=True) dest_bytes = StringIO() dest_image.save(dest_bytes, format="JPEG") self.storage.save(self._get_thumbnail_name(size), ContentFile(dest_bytes.getvalue()))
def resize_image(src, dst, size, remove_src=True): """Resizes and image from src, to dst. Returns width and height.""" if src == dst: raise Exception("src and dst can't be the same: %s" % src) dirname = os.path.dirname(dst) if not os.path.exists(dirname): os.makedirs(dirname) im = Image.open(src) im = im.convert('RGBA') im = processors.scale_and_crop(im, size) im.save(dst, 'png') if remove_src: os.remove(src) return im.size
def resize_image(source, destination, size=None): """Resizes and image from src, to dst. Returns a tuple of new width and height, original width and height. When dealing with local files it's up to you to ensure that all directories exist leading up to the dst filename. """ if source == destination: raise Exception("source and destination can't be the same: %s" % source) with storage.open(source, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') original_size = im.size if size: im = processors.scale_and_crop(im, size) with storage.open(destination, 'wb') as fp: im.save(fp, 'png') pngcrush_image(destination) return (im.size, original_size)
def resize_image(src, dst, size=None, remove_src=True, storage=private_storage): """ Resizes and image from src, to dst. Returns width and height. """ if src == dst: raise Exception("src and dst can't be the same: %s" % src) with storage.open(src, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') if size: im = processors.scale_and_crop(im, size) with storage.open(dst, 'wb') as fp: im.save(fp, 'png') if remove_src: storage.delete(src) return im.size
def resize_image(source, destination, size=None): """Resizes and image from src, to dst. Returns a tuple of new width and height, original width and height. When dealing with local files it's up to you to ensure that all directories exist leading up to the dst filename. """ if source == destination: raise Exception( "source and destination can't be the same: %s" % source) with storage.open(source, 'rb') as fp: im = Image.open(fp) im = im.convert('RGBA') original_size = im.size if size: im = processors.scale_and_crop(im, size) with storage.open(destination, 'wb') as fp: # Save the image to PNG in destination file path. Don't keep the ICC # profile as it can mess up pngcrush badly (mozilla/addons/issues/697). im.save(fp, 'png', icc_profile=None) pngcrush_image(destination) return (im.size, original_size)
def test_croup_rounding(self): image = create_image(size=(2400, 3620)) size = (110, 1000) cropped = processors.scale_and_crop(image, size, crop=True) self.assertEqual(cropped.size, size)
def test_crop_smart(self): image = create_image() smart_crop = processors.scale_and_crop(image, (600, 600), crop='smart') expected = image.crop([78, 0, 678, 600]) self.assertImagesEqual(smart_crop, expected)
def test_zoom_scale(self): image = create_image(size=(2400, 3620)) size = (100, 100) scaled = processors.scale_and_crop(image, size, zoom=40) self.assertEqual(scaled.size, (66, 100))
def scale_and_crop_with_subject_location(im, size, subject_location=False, zoom=None, crop=False, upscale=False, **kwargs): """ Like ``easy_thumbnails.processors.scale_and_crop``, but will use the coordinates in ``subject_location`` to make sure that that part of the image is in the center or at least somewhere on the cropped image. Please not that this does *not* work correctly if the image has been resized by a previous processor (e.g ``autocrop``). ``crop`` needs to be set for this to work, but any special cropping parameters will be ignored. """ subject_location = normalize_subject_location(subject_location) if not (subject_location and crop): # use the normal scale_and_crop return processors.scale_and_crop(im, size, zoom=zoom, crop=crop, upscale=upscale, **kwargs) # for here on we have a subject_location and cropping is on # --snip-- this is a copy and paste of the first few # lines of ``scale_and_crop`` source_x, source_y = [float(v) for v in im.size] target_x, target_y = [float(v) for v in size] if crop or not target_x or not target_y: scale = max(target_x / source_x, target_y / source_y) else: scale = min(target_x / source_x, target_y / source_y) # Handle one-dimensional targets. if not target_x: target_x = source_x * scale elif not target_y: target_y = source_y * scale if zoom: if not crop: target_x = round(source_x * scale) target_y = round(source_y * scale) scale *= (100 + int(zoom)) / 100.0 if scale < 1.0 or (scale > 1.0 and upscale): im = im.resize((int(source_x * scale), int(source_y * scale)), resample=Image.ANTIALIAS) # --endsnip-- begin real code # =============================== # subject location aware cropping # =============================== # res_x, res_y: the resolution of the possibly already resized image res_x, res_y = [float(v) for v in im.size] # subj_x, subj_y: the position of the subject (maybe already re-scaled) subj_x = res_x * float(subject_location[0]) / source_x subj_y = res_y * float(subject_location[1]) / source_y ex = (res_x - min(res_x, target_x)) / 2 ey = (res_y - min(res_y, target_y)) / 2 fx, fy = res_x - ex, res_y - ey # box_width, box_height: dimensions of the target image box_width, box_height = fx - ex, fy - ey # try putting the box in the center around the subject point # (this will be partially outside of the image in most cases) tex, tey = subj_x - (box_width / 2), subj_y - (box_height / 2) tfx, tfy = subj_x + (box_width / 2), subj_y + (box_height / 2) if tex < 0: # its out of the img to the left, move both to the right until tex is 0 tfx = tfx - tex # tex is negative! tex = 0 elif tfx > res_x: # its out of the img to the right tex = tex - (tfx - res_x) tfx = res_x if tey < 0: # its out of the img to the top, move both to the bottom until tey is 0 tfy = tfy - tey # tey is negative!) tey = 0 elif tfy > res_y: # its out of the img to the bottom tey = tey - (tfy - res_y) tfy = res_y if ex or ey: crop_box = ((int(tex), int(tey), int(tfx), int(tfy))) if FILER_SUBJECT_LOCATION_IMAGE_DEBUG: # draw elipse on focal point for Debugging draw = ImageDraw.Draw(im) esize = 10 draw.ellipse(((subj_x - esize, subj_y - esize), (subj_x + esize, subj_y + esize)), outline="#FF0000") im = im.crop(crop_box) return im
def test_zoom_crop(self): image = create_image(size=(2400, 3620)) size = (110, 1000) cropped = processors.scale_and_crop(image, size, crop=True, zoom=40) self.assertEqual(cropped.size, size)
def process(cls, image, matcher): from easy_thumbnails.processors import scale_and_crop width = int(matcher.group(1)) height = int(matcher.group(2)) return scale_and_crop(im=image, size=(width, height), crop="smart")
from easy_thumbnails.processors import scale_and_crop from PIL import Image im = Image.open('/home/chris/Pictures/luke-small.jpg') scale_and_crop(im, (600, 600), crop="smart").show() #target_width = 500 #dx = im.size[0] - target_width # #left, top = 0, 0 #right, bottom = im.size # #while dx: # slice = min(dx, max(dx / 5, 10)) # print [left, top, right, bottom] # half = (right - left) // 2 # print half # start = im.crop([left, top, left + slice, bottom]) # end = im.crop([right - slice, top, right, bottom]) # start_e = image_entropy(start) # end_e = image_entropy(end) # print start_e, end_e # if start_e >= end_e: # right -= slice # else: # left += slice
def scale_and_crop_with_subject_location(im, size, subject_location=False, crop=False, upscale=False, **kwargs): """ Like ``easy_thumbnails.processors.scale_and_crop``, but will use the coordinates in ``subject_location`` to make sure that that part of the image is in the center or at least somewhere on the cropped image. Please not that this does *not* work correctly if the image has been resized by a previous processor (e.g ``autocrop``). ``crop`` needs to be set for this to work, but any special cropping parameters will be ignored. """ subject_location = normalize_subject_location(subject_location) if not (subject_location and crop): # use the normal scale_and_crop return processors.scale_and_crop(im, size, crop=crop, upscale=upscale, **kwargs) # for here on we have a subject_location and cropping is on # --snip-- this is a copy and paste of the first few # lines of ``scale_and_crop`` source_x, source_y = [float(v) for v in im.size] target_x, target_y = [float(v) for v in size] if crop or not target_x or not target_y: scale = max(target_x / source_x, target_y / source_y) else: scale = min(target_x / source_x, target_y / source_y) # Handle one-dimensional targets. if not target_x: target_x = source_x * scale elif not target_y: target_y = source_y * scale if scale < 1.0 or (scale > 1.0 and upscale): im = im.resize((int(source_x * scale), int(source_y * scale)), resample=Image.ANTIALIAS) # --endsnip-- begin real code # =============================== # subject location aware cropping # =============================== # res_x, res_y: the resolution of the possibly already resized image res_x, res_y = [float(v) for v in im.size] # subj_x, subj_y: the position of the subject (maybe already re-scaled) subj_x = res_x * float(subject_location[0]) / source_x subj_y = res_y * float(subject_location[1]) / source_y ex = (res_x - min(res_x, target_x)) / 2 ey = (res_y - min(res_y, target_y)) / 2 fx, fy = res_x - ex, res_y - ey # box_width, box_height: dimensions of the target image box_width, box_height = fx - ex, fy - ey # try putting the box in the center around the subject point # (this will be partially outside of the image in most cases) tex, tey = subj_x - (box_width / 2), subj_y - (box_height / 2) tfx, tfy = subj_x + (box_width / 2), subj_y + (box_height / 2) if tex < 0: # its out of the img to the left, move both to the right until tex is 0 tfx = tfx - tex # tex is negative! tex = 0 elif tfx > res_x: # its out of the img to the right tex = tex - (tfx - res_x) tfx = res_x if tey < 0: # its out of the img to the top, move both to the bottom until tey is 0 tfy = tfy - tey # tey is negative!) tey = 0 elif tfy > res_y: # its out of the img to the bottom tey = tey - (tfy - res_y) tfy = res_y if ex or ey: crop_box = ((int(tex), int(tey), int(tfx), int(tfy))) if FILER_SUBJECT_LOCATION_IMAGE_DEBUG: # draw elipse on focal point for Debugging draw = ImageDraw.Draw(im) esize = 10 draw.ellipse(((subj_x - esize, subj_y - esize), (subj_x + esize, subj_y + esize)), outline="#FF0000") im = im.crop(crop_box) return im
def process(cls, image, matcher): from easy_thumbnails.processors import scale_and_crop width = int(matcher.group(1)) height = int(matcher.group(2)) return scale_and_crop(im=image, size=(width,height), crop="smart")