A custom templatetag for inlining image in the browser. The principe is to base64 encode the image and avoid a http request. There is a cache handling, you just have to specify a writable directory.
An example of the utilisation (template part): http://djangosnippets.org/snippets/2267/
The explication on http://raphaelbeck.wordpress.com/2010/11/14/make-inline-images-to-improve-performance-with-django-template-tags/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | # -*- coding: utf-8 -*-
"""
django templates tags for images
@author: R. BECK
@version: 0.1
"""
#from __future__ import with_statement #Python 2.5
import base64
import os
import Image
from re import compile as compile_re
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from django.conf import settings
from django.template import TemplateSyntaxError, Node, Library, Template
register = Library()
TEMPLATE_DEBUG = settings.TEMPLATE_DEBUG
MEDIA_ROOT = settings.MEDIA_ROOT
CACHE_DIR = "/tmp"
templatevar_re = compile_re("\{\{(.+)\}\}")
media_re = compile_re("\{\{MEDIA_ROOT|MEDIA_URL\}\}")
class EmbeddedImgNode(Node):
"""Image node parser for rendering html inline base64 image"""
def __init__(self, attributes):
self.attrs = {}
attrs = self.attrs
for attr_value in attributes:
try:
attr, value = attr_value.split('=', 1)
except ValueError, val_err:
raise TemplateSyntaxError(u"Syntax Error :", val_err)
attrs[attr] = value
src = attrs.get('src')
if not src:
raise TemplateSyntaxError(u"You have to specify a non-empty src \
attribute")
def _encode_img(self, file_path):
"""Returns image base64 string representation and makes a cache file"""
filename = file_path.rpartition(os.sep)[2]
need_cache = True
content = ""
cache_file = "%s_cache" % os.path.join(CACHE_DIR, filename)
try:
with open(cache_file, 'r') as cached_file:
content = cached_file.read()
need_cache = False
except IOError:
pass
if need_cache:
try:
image = open(file_path, 'r')
out = StringIO()
base64.encode(image, out)
content = out.getvalue().replace('\n', '')
except IOError:
pass
else:
try:
with open(cache_file, 'w+') as cached_file:
cached_file.write(content)
except IOError:
pass
return content
def _render_img(self):
"""Prepare image attributes"""
attrs = self.attrs
attrs_get = attrs.get
src = attrs_get('src')
height = attrs_get('height')
width = attrs_get('width')
if media_re.search(src):
src = src.replace('{{MEDIA_ROOT}}', '') \
.replace('{{MEDIA_URL}}', '')
src = src.replace('"', '')
src = os.path.join(MEDIA_ROOT, src)
try:
img = Image.open(src)
_width, _height = img.size
_format = 'image/%s' % img.format
if not height:
attrs['height'] = '%spx' % _height
if not width:
attrs['width'] = '%spx' % _width
b64encoded = self._encode_img(img.filename)
attrs['src'] = "data:%s;base64,%s" % (_format, b64encoded)
except IOError:
attrs['src'] = ""
def render(self, context):
self._render_img()
attrs = self.attrs
search = templatevar_re.search
for k, v in attrs.iteritems():
if search(v):
attrs[k] = Template(v).render(context)
return """<img %s />""" % ' '.join(['%s=%s' % (k, v if v else '""')
for k, v in attrs.iteritems()])
@register.tag(name="embedded_img")
def do_embedded_img(parser, token):
return EmbeddedImgNode(token.split_contents()[1:])
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.