def put(self, src, delete_local=True, fix_orientation=False): """ Put local file to storage Generates a uuid for the file, tells backend to accept it by that id and removes original on success. """ if not os.path.exists(src): msg = 'Unable to find local file [{}]' raise x.LocalFileNotFound(msg.format(src)) path = Path(src) extension = ''.join(path.suffixes)[1:] name = path.name.replace('.' + extension, '') extension = utils.normalize_extension(extension) filename = name + '.' + extension id = utils.generate_id(filename) # fix image orientation before accepting if fix_orientation: Resizer.fix_orientation_and_save(src) self.backend.put_variant(src, id, filename.lower()) if delete_local: os.remove(src) return id
def test_correct_bad_orientation2(self): """ REGRESSION: correct bad orientation on an image """ img = self.files['orientation2'] filename = img['file'] target_size = '160x96' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) Resizer.auto_crop(src, dst, target_size) result = Image.open(dst)
def test_integration_fit_no_upscale_smaller_original2(self): """ INTEGRATION: Fit, no upscale, src smaller """ img = self.files['orientation'] filename = img['file'] target_size = '300x100' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) Resizer.auto_crop(src, dst, target_size) result = Image.open(dst)
def test_orientation_fixer_with_unicode_in_exif(self): """ REGRESSION: Images with unicode Exif data can be rotated """ path = os.path.join(os.getcwd(), 'shiftmedia', 'tests', 'test_assets', 'unicode_exif.jpg') img = Image.open(path) img, exif = Resizer.fix_orientation(img)
def test_integration_fit_upscale_one_side_smaller(self): """ INTEGRATION: Fit, upscale, one side smaller """ img = self.files['vertical'] # 248x768 filename = img['file'] target_size = '300x500' mode = Resizer.RESIZE_TO_FIT upscale = True self.prepare_uploads() src = os.path.join(self.upload_path, filename) result = Resizer.auto_crop_img(src, target_size, mode, upscale) self.assertEquals(161, result.size[0]) self.assertEquals(500, result.size[1])
def test_integration_fit_no_upscale_bigger_original(self): """ INTEGRATION: Fit, no upscale, original bigger""" img = self.files['vertical'] # 248x768 filename = img['file'] target_size = '200x300' mode = Resizer.RESIZE_TO_FIT upscale = False self.prepare_uploads() src = os.path.join(self.upload_path, filename) result = Resizer.auto_crop_img(src, target_size, mode, upscale) self.assertEquals(96, result.size[0]) self.assertEquals(300, result.size[1])
def test_resize_single_frame_gif(self): """ Resizing single frame GIF image """ filename = 'single_frame.gif' target_size = '50x50' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) result = Resizer.auto_crop(src, dst, target_size) self.assertTrue(os.path.isfile(result)) out = Image.open(result) self.assertEquals(50, out.size[0]) self.assertEquals(50, out.size[1])
def test_resize_jpeg(self): """ Resizing JPG image """ filename = 'original_vertical.jpg' target_size = '200x300' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) result = Resizer.auto_crop(src, dst, target_size) self.assertTrue(os.path.isfile(result)) out = Image.open(result) self.assertEquals(200, out.size[0]) self.assertEquals(300, out.size[1])
def test_integration_fill_upscale_original_bigger(self): """ Fill, upscale, original bigger """ img = self.files['vertical'] # 248x768 filename = img['file'] target_size = '200x300' mode = Resizer.RESIZE_TO_FILL upscale = True self.prepare_uploads() src = os.path.join(self.upload_path, filename) result = Resizer.auto_crop_img(src, target_size, mode, upscale) self.assertEquals(200, result.size[0]) self.assertEquals(300, result.size[1])
def test_integration_fill_no_upscale_one_side_smaller(self): """ Fill, no upscale, one side smaller """ img = self.files['vertical'] # 248x768 filename = img['file'] target_size = '150x900' mode = Resizer.RESIZE_TO_FILL upscale = False self.prepare_uploads() src = os.path.join(self.upload_path, filename) result = Resizer.auto_crop_img(src, target_size, mode, upscale) self.assertEquals(150, result.size[0]) self.assertEquals(768, result.size[1])
def test_resize_with_conversion(self): """ Resizing image with format conversion""" filename = 'single_frame.gif' target_size = '50x50' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) result = Resizer.auto_crop(src, dst, target_size, format='JPEG') self.assertTrue(os.path.isfile(result)) out = Image.open(result) self.assertEquals(50, out.size[0]) self.assertEquals(50, out.size[1]) self.assertTrue(isinstance(out, JpegImagePlugin.JpegImageFile))
def test_resize_animated_gif(self): """ Resizing animated GIF image """ filename = 'test.gif' target_size = '100x100' self.prepare_uploads() src = os.path.join(self.upload_path, filename) dst = os.path.join(self.tmp_path, filename) result = Resizer.auto_crop(src, dst, target_size) self.assertTrue(os.path.isfile(result)) out = Image.open(result) self.assertEquals(100, out.size[0]) self.assertEquals(100, out.size[1]) self.assertTrue(out.info['duration'] > 0)
def create_resize(self, url): """ Create resize Accepts storage URL of a resize, parses and validates it and then creates the resize to be put back to storage. :param url: string - url of resize to be created :return: string - same url on success """ id, filename = self.backend.parse_url(url) params = self.paths.filename_to_resize_params(id, filename) mode = params['resize_mode'] modes = ['auto', 'manual'] if mode not in modes: err = 'Resize mode [' + mode + '] is not yet implemented.' raise x.NotImplementedError(err) local_original = self.backend.retrieve_original(id, self._tmp_path) local_resize = os.path.join(self._tmp_path, id, params['filename']) factor = Resizer.RESIZE_TO_FIT if params['factor'] == 'fill': factor = Resizer.RESIZE_TO_FILL resize = Resizer.auto_crop( src=local_original, dst=local_resize, size=params['target_size'], mode= factor, upscale=params['upscale'], format=params['output_format'], quality=params['quality'] ) try: self.backend.put_variant(resize, id, filename, force=True) except x.FileExists: pass os.remove(local_original) os.remove(resize) tmp_dir = os.path.join(self._tmp_path, id) if not os.listdir(tmp_dir): os.rmdir(tmp_dir) return url