def test_unregister_methods(self): """Ensure versatileimagefield_registry unregister methods work.""" self.assertIn('crop', versatileimagefield_registry._sizedimage_registry) versatileimagefield_registry.unregister_sizer('crop') self.assertNotIn('crop', versatileimagefield_registry._sizedimage_registry) versatileimagefield_registry.register_sizer('crop', CroppedImage) self.assertIn('invert', versatileimagefield_registry._filter_registry) versatileimagefield_registry.unregister_filter('invert') self.assertNotIn('invert', versatileimagefield_registry._filter_registry) versatileimagefield_registry.register_filter('invert', InvertImage)
def test_registration_exceptions(self): """ Ensures all registration-related exceptions fire as expected """ class A(object): pass with self.assertRaises(InvalidSizedImageSubclass): versatileimagefield_registry.register_sizer('a', A) with self.assertRaises(InvalidFilteredImageSubclass): versatileimagefield_registry.register_filter('a', A) with self.assertRaises(UnallowedSizerName): versatileimagefield_registry.register_sizer('chunks', CroppedImage) with self.assertRaises(UnallowedFilterName): versatileimagefield_registry.register_filter('_poop', InvertImage) with self.assertRaises(AlreadyRegistered): versatileimagefield_registry.register_sizer('crop', CroppedImage) with self.assertRaises(AlreadyRegistered): versatileimagefield_registry.register_filter('invert', InvertImage) with self.assertRaises(NotRegistered): versatileimagefield_registry.unregister_sizer('poop') with self.assertRaises(NotRegistered): versatileimagefield_registry.unregister_filter('poop')
def test_registration_exceptions(self): """ Ensures all registration-related exceptions fire as expected """ class A(object): pass with self.assertRaises(InvalidSizedImageSubclass): versatileimagefield_registry.register_sizer('a', A) with self.assertRaises(InvalidFilteredImageSubclass): versatileimagefield_registry.register_filter('a', A) with self.assertRaises(UnallowedSizerName): versatileimagefield_registry.register_sizer('chunks', CroppedImage) with self.assertRaises(UnallowedFilterName): versatileimagefield_registry.register_filter('_poop', InvertImage) with self.assertRaises(AlreadyRegistered): versatileimagefield_registry.register_sizer('crop', CroppedImage) with self.assertRaises(AlreadyRegistered): versatileimagefield_registry.register_filter('invert', InvertImage) with self.assertRaises(NotRegistered): versatileimagefield_registry.unregister_sizer('poop') with self.assertRaises(NotRegistered): versatileimagefield_registry.unregister_filter('poop')
from versatileimagefield.versatileimagefield import CroppedImage from versatileimagefield.datastructures.sizedimage import SizedImage from versatileimagefield.registry import versatileimagefield_registry from PIL import Image class ThumbCropImage(CroppedImage): """ Resize an image first, then crop """ filename_key = 'thumbcrop' def process_image(self, image, image_format, save_kwargs, width, height): old_width, old_height = image.size ratio = max(width / old_width, height / old_height) image.resize((round(old_width * ratio), round(old_height * ratio)), resample=Image.LANCZOS) return super().process_image( image, image_format, save_kwargs, width, height, ) versatileimagefield_registry.register_sizer('thumbcrop', ThumbCropImage)
save_kwargs['icc_profile'] = None return super(CustomThumbnailImage, self).process_image(image, image_format, save_kwargs, width, height) class CustomCroppedImage(CroppedImage): def process_image(self, image, image_format, save_kwargs, width, height): save_kwargs['icc_profile'] = None return super(CustomCroppedImage, self).process_image(image, image_format, save_kwargs, width, height) versatileimagefield_registry.unregister_sizer('thumbnail') versatileimagefield_registry.register_sizer('thumbnail', CustomThumbnailImage) versatileimagefield_registry.unregister_sizer('crop') versatileimagefield_registry.register_sizer('crop', CustomCroppedImage) def image_upload_to_dispatcher(instance, filename): """ Dispatch function to allow overriding of ``image_upload_to`` method. Outside the model for fixing an issue with Django's migrations on Python 2. """ return instance.image_upload_to(filename) class ImageMixin(models.Model): def image_upload_to(self, filename): """
# Solution derived from: http://stackoverflow.com/a/4905209/1149774 if image_format == 'GIF': zoom_image.putpalette(palette) zoom_image.save(imagefile, **save_kwargs) return imagefile class ZoomImage75(ZoomImage): filename_key = 'zoom_75' filename_key_regex = r'zoom_75-c[0-9-]+__[0-9-]+' zoom_percentage = .75 class ZoomImage50(ZoomImage): filename_key = 'zoom_50' filename_key_regex = r'zoom_50-c[0-9-]+__[0-9-]+' zoom_percentage = .5 class ZoomImage33(ZoomImage): filename_key = 'zoom_33' filename_key_regex = r'zoom_33-c[0-9-]+__[0-9-]+' zoom_percentage = .33 versatileimagefield_registry.register_sizer('zoom_75', ZoomImage75) versatileimagefield_registry.register_sizer('zoom_50', ZoomImage50) versatileimagefield_registry.register_sizer('zoom_33', ZoomImage33)
class ThumbnailImage(SizedImage): """ Sizes an image down to fit within a bounding box See the `process_image()` method for more information """ filename_key = 'thumbnail' def process_image(self, image, image_format, save_kwargs, width=400, height=400): """ Returns a StringIO instance of `image` that will fit within a bounding box as specified by `width`x`height` """ imagefile = io.BytesIO() image.thumbnail((width, height), Image.ANTIALIAS) image.save(imagefile, **save_kwargs) return imagefile # Registering the ThumbnailSizer to be available on VersatileImageField # via the `thumbnail` attribute versatileimagefield_registry.unregister_sizer('thumbnail') versatileimagefield_registry.register_sizer('thumbnail', ThumbnailImage)