hide emails with PIL - template filter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from PIL import Image, ImageDraw, ImageFont
import md5
import os
import sys

def mailhide(value):
    email_md5 = md5.new(value).hexdigest()
    email_path = os.path.join(MEDIA_ROOT, EMAIL_THUMBNAILS).replace('\\', '/')
    em_file_path = os.path.join(email_path, email_md5 + '.png').replace('\\', '/')
    if not os.path.exists(email_path):
       os.mkdir(email_path)
    if not os.path.exists(em_file_path):
        img = Image.new('RGBA',(1,1))
        font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
        draw = ImageDraw.ImageDraw(img)
        w,h = draw.textsize(value, font = font)
        img = img.resize((w,h))
        draw = ImageDraw.ImageDraw(img)
        draw.text((0,0),value, font = font, fill = FONT_COLOR)
        img.save(em_file_path)
    
    result = '<img src = "%s%s/%s.png"/>'%(MEDIA_URL, EMAIL_THUMBNAILS,email_md5)
    
    return mark_safe(result)

More like this

  1. Template Tag to protect the E-mail address by nitinhayaran 3 years, 3 months ago
  2. Email Munger by cootetom 4 years, 4 months ago
  3. Protect anti robots template tag by marinho 5 years ago
  4. Auto HTML Linebreak filter by punteney 5 years, 1 month ago
  5. Unsharp Mask with PIL and PythonMagick by VidJa 4 years, 4 months ago

Comments

NickJones (on November 18, 2010):

I have updated this snippet slightly to allow the ability to configure each parameter per filter call and also adjust the letter spacing. The resulting image is also auto-cropped:

def mailhide(value, arg):
    font_name, font_size, font_colour, letter_spacing = arg.split(',')
    letter_spacing = int(letter_spacing)
    EMAIL_THUMBNAILS = 'img/content/emails/'
    email_md5 = md5.new(value).hexdigest()
    email_path = os.path.join(settings.MEDIA_ROOT, EMAIL_THUMBNAILS).replace('\\', '/')
    em_file_path = os.path.join(email_path, email_md5 + '.png').replace('\\', '/')
    if not os.path.exists(email_path):
       os.mkdir(email_path)
    if not os.path.exists(em_file_path):
        img = Image.new('RGBA',(1,1))
        font = ImageFont.truetype(settings.MEDIA_ROOT+'fonts/'+font_name+'.ttf', int(font_size))
        draw = ImageDraw.ImageDraw(img)
        w,h = draw.textsize(value, font=font)
        # A value of 20 here keeps the text from being truncated down to a letter_spacing
        # value of at least -6, any further and the text is illegible anyway
        img = img.resize((w+(len(value)*letter_spacing)+20,h))
        draw = ImageDraw.ImageDraw(img)
        x = 0
        for letter in value:
            draw.text((x,0), letter, font=font, fill=font_colour)
            w,h = draw.textsize(letter, font=font)
            x = x+w+letter_spacing

        # Adapted from http://www.velocityreviews.com/forums/t324237-auto-crop-in-pil.html
        # Image auto-crop function needs two new images as a result of RGBA use
        alt_colour = "#000" if font_colour == "#fff" else "#fff"
        bg_1 = Image.new("RGB", img.size, alt_colour)
        bg_2 = Image.new("RGB", img.size, alt_colour)
        bg_2.paste(img, img)
        diff = ImageChops.difference(bg_1, bg_2)
        bbox = diff.getbbox()
        img  = img.crop(bbox)
        img.save(em_file_path)

    result = '<img src = "%s%s/%s.png"/>'%(settings.MEDIA_URL, EMAIL_THUMBNAILS, email_md5)
    return mark_safe(result)

to be used as so:

{% text_var|mailhide:"Helvetica,18,#000,-1" %}

#

NickJones (on November 18, 2010):

Also, if you change

img = Image.new('RGBA', (1,1))

into

img = Image.new('RGBA', (1,1), (255,0,0,0))

it anti-aliases non-black fonts correctly. You can also remove

draw = ImageDraw.ImageDraw(img)
w,h = draw.textsize(value, font=font)

and replace it with

w,h = font.getsize(value)

#

NickJones (on November 18, 2010):

Sorry one more change, if you use the hex_to_rgb snippet from http://stackoverflow.com/questions/214359/converting-hex-to-rgb-and-vice-versa , the new image line should actually read

img = Image.new('RGBA', (1,1), hex_to_rgb(font_colour)+(0,))

#

(Forgotten your password?)