def request_resource(self, url, **kwargs): maxwidth = kwargs.get('maxwidth', None) maxheight = kwargs.get('maxheight', None) # calculate the appropriate bounds for width and height w, h = size_to_nearest(maxwidth, maxheight, self.IMAGE_SIZES, True) # get the path, i.e. /media/img/kitties.jpg image_path = re.match(self.regex, url).groups()[0] # create the entire url as it would be on site, minus the filename base_url, ext = url.rsplit('.', 1) # create the file path minus the extension base_path, ext = image_path.rsplit('.', 1) append = '_%sx%s.%s' % (w, h, ext) new_path = '%s%s' % (base_path, append) if not default_storage.exists(new_path): # open the original to calculate its width and height source_file = default_storage.open(image_path) img = Image.open(source_file) # retrieve image format and dimensions format = img.format img_width, img_height = img.size # do the math-y parts new_width, new_height = scale(img_width, img_height, w, h) img = img.resize((new_width, new_height), Image.ANTIALIAS) img_buffer = StringIO() img.MAXBLOCK = 1024 * 1024 img.save(img_buffer, format=format) source_file.close() default_storage.save(new_path, ContentFile(img_buffer.getvalue())) new_url = '%s%s' % (base_url, append) # get just the filename, i.e. test.jpg - used for generated the title # of the returned oembed resource image_filename = image_path.rsplit('/', 1)[-1] data = { 'type': 'photo', 'provider_name': '', 'version': '1.0', 'width': w, 'height': h, 'title': image_filename, 'url': new_url, 'author_name': '', 'author_url': '' } return OEmbedResource.create(data)
def request_resource(self, url, **kwargs): maxwidth = kwargs.get('maxwidth', None) maxheight = kwargs.get('maxheight', None) # calculate the appropriate bounds for width and height w, h = size_to_nearest(maxwidth, maxheight, self.IMAGE_SIZES, True) # get the path, i.e. /media/img/kitties.jpg image_path = re.match(self.regex, url).groups()[0] # create the entire filename as it would be on disk filename = settings.MEDIA_ROOT + image_path # create the entire url as it would be on site, minus the filename base_url, ext = url.rsplit('.', 1) # create the file path on disk minus the extension base_file, ext = filename.rsplit('.', 1) append = '_%sx%s.%s' % (w, h, ext) new_filename = '%s%s' % (base_file, append) if not os.path.isfile(new_filename): # open the original to calculate its width and height img = Image.open(filename) img_width, img_height = img.size # do the math-y parts new_width, new_height = scale(img_width, img_height, w, h) img = img.resize((new_width, new_height), Image.ANTIALIAS) img.save(new_filename) new_url = '%s%s' % (base_url, append) # get just the filename, i.e. test.jpg - used for generated the title # of the returned oembed resource image_filename = image_path.rsplit('/', 1)[1] data = { 'type': 'photo', 'provider_name': '', 'version': '1.0', 'width': w, 'height': h, 'title': image_filename, 'url': new_url, 'author_name': '', 'author_url': '' } return OEmbedResource.create(data)
def request_resource(self, url, **kwargs): maxwidth = kwargs.get('maxwidth', None) maxheight = kwargs.get('maxheight', None) # calculate the appropriate bounds for width and height w, h = size_to_nearest(maxwidth, maxheight, self.IMAGE_SIZES, True) # get the path, i.e. /media/img/kitties.jpg image_path = re.match(self.regex, url).groups()[0] # create the entire url as it would be on site, minus the filename base_url, ext = url.rsplit('.', 1) # create the file path minus the extension base_path, ext = image_path.rsplit('.', 1) append = '_%sx%s.%s' % (w, h, ext) new_path = '%s%s' % (base_path, append) if not default_storage.exists(new_path): # open the original to calculate its width and height source_file = default_storage.open(image_path) img = Image.open(source_file) # retrieve image format and dimensions format = img.format img_width, img_height = img.size # do the math-y parts new_width, new_height = scale(img_width, img_height, w, h) img = img.resize((new_width, new_height), Image.ANTIALIAS) img_buffer = StringIO() img.MAXBLOCK = 1024*1024 img.save(img_buffer, format=format) source_file.close() default_storage.save(new_path, ContentFile(img_buffer.getvalue())) new_url = '%s%s' % (base_url, append) # get just the filename, i.e. test.jpg - used for generated the title # of the returned oembed resource image_filename = image_path.rsplit('/', 1)[-1] data = {'type': 'photo', 'provider_name': '', 'version': '1.0', 'width': w, 'height': h, 'title': image_filename, 'url': new_url, 'author_name': '', 'author_url': ''} return OEmbedResource.create(data)
def test_scale(self): self.assertEqual(scale(640, 480, 320), (320, 240)) self.assertEqual(scale(640, 480, 500, 240), (320, 240)) self.assertEqual(scale(640, 480, 320, 500), (320, 240)) self.assertEqual(scale(640, 480, 320, 240), (320, 240)) self.assertEqual(scale(640, 480, 700), (640, 480)) self.assertEqual(scale(640, 480, 700, 500), (640, 480))
def resize(self, image_field, new_width=None, new_height=None): """ Resize an image to the 'best fit' width & height, maintaining the scale of the image, so a 500x500 image sized to 300x400 will actually be scaled to 300x300. Params: image: ImageFieldFile to be resized (i.e. model.image_field) new_width & new_height: desired maximums for resizing Returns: the url to the new image and the new width & height (http://path-to-new-image, 300, 300) """ if not isinstance(image_field, ImageFieldFile): raise ValueError( 'image_field must be an instance of django.db.models.fields.files.ImageFieldFile' ) if image_field.field.width_field and image_field.field.height_field: # use model fields current_width = getattr(image_field.instance, image_field.field.width_field) current_height = getattr(image_field.instance, image_field.field.height_field) else: # use PIL try: file_obj = storage.default_storage.open(image_field.name, 'rb') img_obj = Image.open(file_obj) current_width, current_height = img_obj.size except IOError: return (image_field.url, 0, 0) # determine if resizing needs to be done (will not scale up) if current_width < new_width: if not new_height or current_height < new_height: return (image_field.url, current_width, current_height) # calculate ratios new_width, new_height = scale(current_width, current_height, new_width, new_height) # use the image_processor defined in the settings, or PIL by default return self._meta.image_processor.resize(image_field, new_width, new_height)
def request_resource(self, url, **kwargs): maxwidth = kwargs.get('maxwidth', None) maxheight = kwargs.get('maxheight', None) # calculate the appropriate bounds for width and height w, h = size_to_nearest(maxwidth, maxheight, self.IMAGE_SIZES, True) # get the path, i.e. /media/img/kitties.jpg image_path = re.match(self.regex, url).groups()[0] # create the entire filename as it would be on disk filename = settings.MEDIA_ROOT + image_path # create the entire url as it would be on site, minus the filename base_url, ext = url.rsplit('.', 1) # create the file path on disk minus the extension base_file, ext = filename.rsplit('.', 1) append = '_%sx%s.%s' % (w, h, ext) new_filename = '%s%s' % (base_file, append) if not os.path.isfile(new_filename): # open the original to calculate its width and height img = Image.open(filename) img_width, img_height = img.size # do the math-y parts new_width, new_height = scale(img_width, img_height, w, h) img = img.resize((new_width, new_height), Image.ANTIALIAS) img.save(new_filename) new_url = '%s%s' % (base_url, append) # get just the filename, i.e. test.jpg - used for generated the title # of the returned oembed resource image_filename = image_path.rsplit('/', 1)[1] data = {'type': 'photo', 'provider_name': '', 'version': '1.0', 'width': w, 'height': h, 'title': image_filename, 'url': new_url, 'author_name': '', 'author_url': ''} return OEmbedResource.create(data)
def resize(self, image_field, new_width=None, new_height=None): """ Resize an image to the 'best fit' width & height, maintaining the scale of the image, so a 500x500 image sized to 300x400 will actually be scaled to 300x300. Params: image: ImageFieldFile to be resized (i.e. model.image_field) new_width & new_height: desired maximums for resizing Returns: the url to the new image and the new width & height (http://path-to-new-image, 300, 300) """ if not isinstance(image_field, ImageFieldFile): raise ValueError('image_field must be an instance of django.db.models.fields.files.ImageFieldFile') if image_field.field.width_field and image_field.field.height_field: # use model fields current_width = getattr(image_field.instance, image_field.field.width_field) current_height = getattr(image_field.instance, image_field.field.height_field) else: # use PIL try: file_obj = storage.default_storage.open(image_field.name, 'rb') img_obj = Image.open(file_obj) current_width, current_height = img_obj.size except IOError: return (image_field.url, 0, 0) # determine if resizing needs to be done (will not scale up) if current_width < new_width: if not new_height or current_height < new_height: return (image_field.url, current_width, current_height) # calculate ratios new_width, new_height = scale(current_width, current_height, new_width, new_height) # use the image_processor defined in the settings, or PIL by default return self._meta.image_processor.resize(image_field, new_width, new_height)