def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop(im, VERSIONS[version_suffix]['width'], VERSIONS[version_suffix]['height'], VERSIONS[version_suffix]['opts']) if not version: version = im # version methods as defined with VERSIONS if 'methods' in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]['methods']: if callable(m): version = m(version) # save version try: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY, optimize=(os.path.splitext(version_path)[1] != '.gif')) except IOError: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) return version_path
def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) icc_profile = im.info.get("icc_profile") im = self._rotate_exif_image(im) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop( im, VERSIONS[version_suffix].get('width', 0), VERSIONS[version_suffix].get('height', 0), VERSIONS[version_suffix].get('opts', '') ) if not version: version = im # version methods as defined with VERSIONS if 'methods' in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]['methods']: if callable(m): version = m(version) # IF need Convert RGB if version.mode not in ("L", "RGB", "RGBA"): version = version.convert("RGB") quality = VERSIONS[version_suffix].get('quality', VERSION_QUALITY) kwargs = { 'format': Image.EXTENSION[ext.lower()], 'quality': quality, 'optimize': (os.path.splitext(version_path)[1] != '.gif'), 'icc_profile': icc_profile, } # save version try: version.save(tmpfile, **kwargs) except IOError: kwargs.pop('optimize') version.save(tmpfile, **kwargs) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) # set permissions if DEFAULT_PERMISSIONS is not None: os.chmod(self.site.storage.path(version_path), DEFAULT_PERMISSIONS) return version_path
def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) icc_profile = im.info.get("icc_profile") im = self._rotate_exif_image(im) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop(im, VERSIONS[version_suffix].get('width', 0), VERSIONS[version_suffix].get('height', 0), VERSIONS[version_suffix].get('opts', '')) if not version: version = im # version methods as defined with VERSIONS if 'methods' in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]['methods']: if callable(m): version = m(version) # IF need Convert RGB if version.mode not in ("L", "RGB", "RGBA"): version = version.convert("RGB") quality = VERSIONS[version_suffix].get('quality', VERSION_QUALITY) kwargs = { 'format': Image.EXTENSION[ext.lower()], 'quality': quality, 'optimize': (os.path.splitext(version_path)[1] != '.gif'), 'icc_profile': icc_profile, } # save version try: version.save(tmpfile, **kwargs) except IOError: kwargs.pop('optimize') version.save(tmpfile, **kwargs) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) # set permissions if DEFAULT_PERMISSIONS is not None: os.chmod(self.site.storage.path(version_path), DEFAULT_PERMISSIONS) return version_path
def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop(im, VERSIONS[version_suffix]['width'], VERSIONS[version_suffix]['height'], VERSIONS[version_suffix]['opts']) if not version: version = im # version methods as defined with VERSIONS if 'methods' in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]['methods']: if callable(m): version = m(version) # IF need Convert RGB # http://stackoverflow.com/questions/21669657/getting-cannot-write-mode-p-as-jpeg-while-operating-on-jpg-image if version.mode not in ("L", "RGB"): version = version.convert("RGB") # save version try: version.save( tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY, optimize=(os.path.splitext(version_path)[1] != '.gif')) except IOError: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) # set permissions if DEFAULT_PERMISSIONS is not None: os.chmod(self.site.storage.path(version_path), DEFAULT_PERMISSIONS) return version_path
def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(tempfile.NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop( im, VERSIONS[version_suffix]["width"], VERSIONS[version_suffix]["height"], VERSIONS[version_suffix]["opts"] ) if not version: version = im # version methods as defined with VERSIONS if "methods" in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]["methods"]: if callable(m): version = m(version) # IF need Convert RGB if ext in [".jpg", ".jpeg"] and version.mode not in ("L", "RGB"): version = version.convert("RGB") # save version try: version.save( tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY, optimize=(os.path.splitext(version_path)[1] != ".gif"), ) except IOError: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) # set permissions if DEFAULT_PERMISSIONS is not None: os.chmod(self.site.storage.path(version_path), DEFAULT_PERMISSIONS) return version_path
def _generate_version(self, version_suffix): """ Generate Version for an Image. value has to be a path relative to the storage location. """ tmpfile = File(NamedTemporaryFile()) try: f = self.site.storage.open(self.path) except IOError: return "" im = Image.open(f) version_path = self.version_path(version_suffix) version_dir, version_basename = os.path.split(version_path) root, ext = os.path.splitext(version_basename) version = scale_and_crop(im, VERSIONS[version_suffix]['width'], VERSIONS[version_suffix]['height'], VERSIONS[version_suffix]['opts']) if not version: version = im # version methods as defined with VERSIONS if 'methods' in VERSIONS[version_suffix].keys(): for m in VERSIONS[version_suffix]['methods']: if callable(m): version = m(version) # IF need Convert RGB # http://stackoverflow.com/questions/21669657/getting-cannot-write-mode-p-as-jpeg-while-operating-on-jpg-image if version.mode not in ("L", "RGB"): version = version.convert("RGB") # save version try: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY, optimize=(os.path.splitext(version_path)[1] != '.gif')) except IOError: version.save(tmpfile, format=Image.EXTENSION[ext.lower()], quality=VERSION_QUALITY) # remove old version, if any if version_path != self.site.storage.get_available_name(version_path): self.site.storage.delete(version_path) self.site.storage.save(version_path, tmpfile) # set permissions if DEFAULT_PERMISSIONS is not None: os.chmod(self.site.storage.path(version_path), DEFAULT_PERMISSIONS) return version_path
def test_width_smaller_but_height_bigger_with_upscale(self): # same with upscale version = scale_and_crop(self.im, 500, 1125, "upscale") self.assertEqual(version.size, (500, 375))
def test_scale_no_upscale_too_wide(self): version = scale_and_crop(self.im, 1500, "", "") self.assertIs(version, self.im)
def test_scale_no_upscale_too_tall(self): version = scale_and_crop(self.im, "", 1125, "") self.assertIs(version, self.im)
def test_width_smaller_but_height_bigger_no_upscale(self): # new width 500 and height 1125 # new width is smaller than original, but new height is bigger # width has higher priority version = scale_and_crop(self.im, 500, 1125, "") self.assertEqual(version.size, (500, 375))
def test_crop_width_and_height_too_large_no_upscale(self): # new width 1500 and height 1500 w. crop > false (upscale missing) version = scale_and_crop(self.im, 1500, 1500, "crop") self.assertEqual(version, False)
def test_do_not_scale_if_desired_size_is_equal_to_original(self): width, height = self.im.size version = scale_and_crop(self.im, width, height, "") self.assertIs(version, self.im) self.assertEqual(version.size, (width, height))
def test_scale_height(self): # new height 375 > 500/375 version = scale_and_crop(self.im, "", 375, "") self.assertEqual(version.size, (500, 375))
def test_scale_crop(self): """ Test scale/crop functionality scale_and_crop(im, width, height, opts) self.f_image (original): width 1000, height 750 """ # new width 500 > 500/375 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 500, "", "") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # new height 375 > 500/375 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, "", 375, "") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # SIZE TOO BIG, BUT NO UPSCALE DEFINED # new width 1500, no upscale > False im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, "", "") self.assertEqual(version, False) # new height 1125, no upscale > False im = Image.open(self.f_image.path_full) version = scale_and_crop(im, "", 1125, "") self.assertEqual(version, False) # new width 1500, height 1125, no upscale > False im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 1125, "") self.assertEqual(version, False) # SIZE TOO BIG, UPSCALE DEFINED # new width 1500, upscale > 1500/1125 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, "", "upscale") self.assertEqual(version.size[0], 1500) self.assertEqual(version.size[1], 1125) # new height 1125, upscale > 1500/1125 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, "", 1125, "upscale") self.assertEqual(version.size[0], 1500) self.assertEqual(version.size[1], 1125) # new width 1500, new height 1125, upscale > 1500/1125 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 1125, "upscale") self.assertEqual(version.size[0], 1500) self.assertEqual(version.size[1], 1125) # new width 1500, new height 1125, upscale > 1500/1125 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 0, "upscale") self.assertEqual(version.size[0], 1500) self.assertEqual(version.size[1], 1125) # SIZE TOO SMALL, UPSCALE DEFINED # width too small, no upscale im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 500, "", "upscale") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # height too small, no upscale im = Image.open(self.f_image.path_full) version = scale_and_crop(im, "", 375, "upscale") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # CROPPING # new width 500 and height 500 w. crop > 500/500 im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 500, 500, "crop") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 500) # new width 1500 and height 1500 w. crop > false (upscale missing) im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 1500, "crop") self.assertEqual(version, False) # new width 1500 and height 1500 w. crop > false (upscale missing) im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 1500, "crop,upscale") self.assertEqual(version.size[0], 1500) self.assertEqual(version.size[1], 1500) # SPECIAL CASES # new width 500 and height 1125 # new width is smaller than original, but new height is bigger # width has higher priority im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 500, 1125, "") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # same with upscale im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 500, 1125, "upscale") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # new width 1500 and height 375 # new width is bigger than original, but new height is smaller # height has higher priority im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 375, "") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375) # same with upscale im = Image.open(self.f_image.path_full) version = scale_and_crop(im, 1500, 375, "upscale") self.assertEqual(version.size[0], 500) self.assertEqual(version.size[1], 375)
def test_scale_width(self): version = scale_and_crop(self.im, 500, "", "") self.assertEqual(version.size, (500, 375))
def test_scale_with_upscale_width(self): version = scale_and_crop(self.im, 1500, "", "upscale") self.assertEqual(version.size, (1500, 1125))
def test_do_not_scale(self): version = scale_and_crop(self.im, "", "", "") self.assertEqual(version.size, self.im.size)
def test_scale_with_upscale_height_too_small_for_upscale(self): version = scale_and_crop(self.im, "", 375, "upscale") self.assertEqual(version.size, (500, 375))
def test_scale_no_upscale_too_wide_and_tall(self): version = scale_and_crop(self.im, 1500, 1125, "") self.assertEqual(version, False)
def test_scale_with_upscale_zero_width_and_height(self): version = scale_and_crop(self.im, 0, 1125, "upscale") self.assertEqual(version.size, (1500, 1125))
def test_crop_width_and_height(self): version = scale_and_crop(self.im, 500, 500, "crop") self.assertEqual(version.size, (500, 500))
def test_crop_width_and_height_too_large_with_upscale(self): version = scale_and_crop(self.im, 1500, 1500, "crop,upscale") self.assertEqual(version.size, (1500, 1500))