src/pyams_file/image.py
changeset 205 a731e29446ca
parent 195 07c9c58698fb
child 209 b146beab5367
--- a/src/pyams_file/image.py	Sun Jul 19 02:01:21 2020 +0200
+++ b/src/pyams_file/image.py	Mon Jul 20 14:53:39 2020 +0200
@@ -10,18 +10,27 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
+import random
 import re
+import sys
 from io import BytesIO
 
 from PIL import Image, ImageFilter
+from pyramid.renderers import render
+from zope.dublincore.interfaces import IZopeDublinCore
 from zope.interface import implementer
 from zope.schema.fieldproperty import FieldProperty
 
+from pyams_file.interfaces import IImage, IResponsiveImage, ISVGImage, IThumbnailGeometry, \
+    IThumbnailer, IThumbnails
+from pyams_utils.adapter import ContextAdapter, adapter_config
+from pyams_utils.request import check_request
+from pyams_utils.url import absolute_url
+
+
+__docformat__ = 'restructuredtext'
+
 from pyams_file import _
-from pyams_file.interfaces import IImage, IResponsiveImage, IThumbnailGeometry, IThumbnailer, IThumbnails
-from pyams_utils.adapter import ContextAdapter, adapter_config
 
 
 WEB_FORMATS = ('JPEG', 'PNG', 'GIF')
@@ -267,3 +276,62 @@
 
     label = _("Large screen thumbnail")
     weight = 13
+
+
+#
+# SVG utilities
+#
+
+def render_svg(image, width=None, height=None, request=None, css_class='', img_class=''):
+    """Render SVG file"""
+    options = {'svg': image}
+    if width or height:
+        options['style'] = 'width: {0}{1}; height: {2}{3};'.format(
+            width, 'px' if isinstance(width, int) else '',
+            height, 'px' if isinstance(height, int) else '')
+    else:
+        options['style'] = ''
+    options['css_class'] = css_class
+    result = render('templates/svg-render.pt', options, request)
+    if img_class:
+        result = result.replace('<svg ', '<svg class="{0}" '.format(img_class))
+    return result
+
+
+def render_img(image, width=None, height=None, request=None,
+               css_class='', img_class='', timestamp=False):
+    """Render image thumbnail"""
+    thumbnail = None
+    thumbnails = IThumbnails(image, None)
+    if thumbnails is not None:
+        if width and height:
+            thumbnail = thumbnails.get_thumbnail('{0}x{1}'.format(width, height))
+        elif width and (width != 'auto'):
+            thumbnail = thumbnails.get_thumbnail('w{0}'.format(width))
+        elif height and (height != 'auto'):
+            thumbnail = thumbnails.get_thumbnail('h{0}'.format(height))
+    if thumbnail is None:
+        thumbnail = image
+    if request is None:
+        request = check_request()
+    url = absolute_url(thumbnail, request)
+    if timestamp:
+        dc = IZopeDublinCore(thumbnail, None)
+        if dc is None:
+            timestamp = random.randint(0, sys.maxsize)
+        else:
+            timestamp = dc.modified.timestamp()
+        url += '?_={0}'.format(timestamp)
+    result = '<img src="{0}" class="{1}" />'.format(url, img_class)
+    if css_class:
+        result = '<div class="{0}">{1}</div>'.format(css_class, result)
+    return result
+
+
+def render_image(image, width=None, height=None, request=None,
+                 css_class='', img_class='', timestamp=False):
+    """Render image"""
+    if ISVGImage.providedBy(image):
+        return render_svg(image, width, height, request, css_class, img_class)
+    else:
+        return render_img(image, width, height, request, css_class, img_class, timestamp)