示例#1
0
class ImageThumbnailer(ContextAdapter):
    """Image thumbnailer adapter"""

    label = _("Default thumbnail")
    section = _("Default thumbnail")
    weight = 1

    def get_default_geometry(self, options=None):    # pylint: disable=unused-argument
        """Default thumbnail geometry"""
        geometry = ThumbnailGeometry()
        width, height = self.context.get_image_size()
        geometry.x1 = 0  # pylint: disable=invalid-name
        geometry.y1 = 0  # pylint: disable=invalid-name
        geometry.x2 = width  # pylint: disable=invalid-name
        geometry.y2 = height  # pylint: disable=invalid-name
        return geometry

    def create_thumbnail(self, target, format=None):
        # pylint: disable=redefined-builtin,too-many-branches
        """Create thumbnail of given size and format

        :param target: size or geometry of the thumbnail
        :param format: image format
        """
        # check thumbnail name
        if isinstance(target, str):
            width, height = tuple(map(int, target.split('x')))
        elif IThumbnailGeometry.providedBy(target):
            width = target.x2 - target.x1
            height = target.y2 - target.y1
        elif isinstance(target, tuple):
            width, height = target
        else:
            return None
        # check format
        with self.context as blob:
            try:
                if blob is None:
                    return None
                image = Image.open(blob)
                if not format:
                    format = image.format
                format = format.upper()
                if format not in WEB_FORMATS:
                    format = 'JPEG'
                # check image mode
                if image.mode in ('P', 'RGBA'):
                    if format == 'JPEG':
                        image = image.convert('RGB')
                    elif image.mode != 'RGBA':
                        image = image.convert('RGBA')
                # generate thumbnail
                new_image = BytesIO()
                image.resize((width, height), Image.ANTIALIAS) \
                    .filter(ImageFilter.UnsharpMask(radius=0.5, percent=100, threshold=0)) \
                    .save(new_image, format)
                return new_image, format.lower()
            finally:
                if blob is not None:
                    blob.close()
示例#2
0
class ImageCardThumbnailer(ImageHorizontalThumbnailer):
    """Image card thumbnail adapter"""

    label = _("Card thumbnail")
    weight = 8

    ratio = (2, 1)
示例#3
0
class ImageBannerThumbnailer(ImageRatioThumbnailer):
    """Image banner thumbnail adapter"""

    label = _("Banner thumbnail")
    weight = 9

    ratio = (5, 1)
示例#4
0
class ImagePanoThumbnailer(ImageHorizontalThumbnailer):
    """Image panoramic thumbnail adapter"""

    label = _("Panoramic thumbnail")
    weight = 7

    ratio = (16, 9)
示例#5
0
class ImageSquareThumbnailer(ImageRatioThumbnailer):
    """Image square thumbnail adapter"""

    label = _("Square thumbnail")
    weight = 6

    ratio = (1, 1)
示例#6
0
class ImagePortraitThumbnailer(ImageRatioThumbnailer):
    """Image portrait thumbnail adapter"""

    label = _("Portrait thumbnail")
    weight = 5

    ratio = (3, 4)
示例#7
0
class ImageSelectionThumbnailer(ImageThumbnailer):
    """Image thumbnailer based on user selection"""

    section = _("Custom selections")

    def create_thumbnail(self, target, format=None):
        # pylint: disable=redefined-builtin,too-many-branches
        # get thumbnail size
        if isinstance(target, str):
            # pylint: disable=assignment-from-no-return
            geometry = IThumbnails(self.context).get_geometry(target)
            match = THUMB_SIZE.match(target)
            if match:
                width, height = tuple(map(int, match.groups()))
            else:
                width = abs(geometry.x2 - geometry.x1)
                height = abs(geometry.y2 - geometry.y1)
        elif IThumbnailGeometry.providedBy(target):
            geometry = target
            width = abs(geometry.x2 - geometry.x1)
            height = abs(geometry.y2 - geometry.y1)
        elif isinstance(target, tuple):
            width, height = target
            geometry = self.get_default_geometry()
        else:
            return None
        # check format
        with self.context as blob:
            try:
                if blob is None:
                    return None
                image = Image.open(blob)
                if not format:
                    format = image.format
                format = format.upper()
                if format not in WEB_FORMATS:
                    format = 'JPEG'
                # check image mode
                if image.mode in ('P', 'RGBA'):
                    if format == 'JPEG':
                        image = image.convert('RGB')
                    elif image.mode != 'RGBA':
                        image = image.convert('RGBA')
                # generate thumbnail
                new_image = BytesIO()
                thumb_size = self.get_thumb_size(width, height, geometry)
                image.crop((geometry.x1, geometry.y1, geometry.x2, geometry.y2)) \
                    .resize(thumb_size, Image.ANTIALIAS) \
                    .filter(ImageFilter.UnsharpMask(radius=0.5, percent=100, threshold=0)) \
                    .save(new_image, format)
                return new_image, format.lower()
            finally:
                if blob is not None:
                    blob.close()

    def get_thumb_size(self, width, height, geometry):
        # pylint: disable=no-self-use,unused-argument
        """Get thumbnail size based on given dimensions"""
        return width, height
示例#8
0
class IFileInfo(Interface):
    """File extended information"""

    title = TextLine(title=_("Title"),
                     required=False)

    description = Text(title=_("Description"),
                       required=False)

    filename = TextLine(title=_("Save file as..."),
                        description=_("Name under which the file will be saved"),
                        required=False)

    language = Choice(title=_("Language"),
                      description=_("File's content language"),
                      vocabulary=BASE_LANGUAGES_VOCABULARY_NAME,
                      required=False)
示例#9
0
class XlImageThumbnailer(ResponsiveImageThumbnailer):
    """EXtra-Large responsive image thumbnailer"""

    label = _("Extra-large screen thumbnail")
    weight = 14
示例#10
0
class LgImageThumbnailer(ResponsiveImageThumbnailer):
    """LarGe responsive image thumbnailer"""

    label = _("Large screen thumbnail")
    weight = 13
示例#11
0
class MdImageThumbnailer(ResponsiveImageThumbnailer):
    """MeDium responsive image thumbnailer"""

    label = _("Medium screen thumbnail")
    weight = 12
示例#12
0
class SmImageThumbnailer(ResponsiveImageThumbnailer):
    """SMall responsive image thumbnailer"""

    label = _("Tablet thumbnail")
    weight = 11
示例#13
0
class XsImageThumbnailer(ResponsiveImageThumbnailer):
    """eXtra-Small responsive image thumbnailer"""

    label = _("Smartphone thumbnail")
    weight = 10
示例#14
0
class ResponsiveImageThumbnailer(ImageSelectionThumbnailer):
    """Responsive image thumbnailer"""

    section = _("Responsive selections")