Base64 Encoding of Images

Today I’m working on an XML feed of events into an enterprise calendar program.  One of the requirements is the base64 encoding of accompanying images. My system gives the option to store the URL to a photo, not to store the image locally.  A bit of a shortcut I know, but I didn’t want to mess with the bureaucracy of the server team to work out the storage a backup of the images.  Luckily, it’s no big deal to Python either way. For a locally stored images, one can convert to base64 pretty easily, given the file name.  Try this:

import base64

image = 'example.jpg'
image_64 = base64.encodestring(open(image,"rb").read())

Not much different working with a URL, as urllib provides the urlopen method to present an online resource with a .read() function:

import base64, urllib

image = urllib.urlopen('http://docs.python.org/_static/py.png')
image_64 = base64.encodestring(image.read())

In this example, I’m using the location of the little Python symbol on the top left of most python.org pages.  Even this small graphic converts to a lot of base64 characters.  Here is the result:

iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A
/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gEGxE4IQYzJ14AAAI3SURBVDjL
ZZNPSFVBFIe/e9+zd3silBCl0SZoU4s2rVq0EB5tQip4UNvATVGu3QRBiyAi2iltWkgbF5EgRhFF
RpiWtrWIzDIV1Pzz7p15M2fmtvDevOqBw8DM9zvnN8ycgF3R/eDtM2mac96ZdrFNxBikqbRV+vHH
/ut9gAZczoe7C3gnF0f6au1OLM5avFi8d1Ea+JvAMSAq8nsKOGs5f2cYJ3Y7rc2PO4BqkS8DdD98
f9tbe1ysCoxOBo1qlEXHJWcM4b5KPU19zleA0o4Clx99eO3EdqVewHsCoFRugUoVghJO7A6H6Vx9
wdtYi27cr5x6dy/03nVtWTU7bWeZh6jNUcAiCaFTURl9A+gs56AviHzh3mnqtdPxm6knfQPLU7Ua
okASQq/agY7yDrG16Mba6Pz48NP56VdrgAApYObGaicPtkovToFLQBKA/WUxTe3FRk4san15aGKg
d3Dj560rrdGJS6FT0X9YYvLuiMKL1kAQOpHZ3PqfyZfP41+9PW1VfzX0RXFSECfgNEmSTgImdDru
F2O0E8vvqZG1auQubAsKooIYYHpGvwA2g+xndQBHgWa6cG0ih5cW/w6VvEq3nChwCoBvs+bL2Z7V
ceBHGTDAIrABpMVuhw+4OiLgLIglOLPYBTQAlfErIeCzjRVg1dtEb1kt5Omv+DTV2YssAN+zNdkz
C42N9brV8WdvYp07seOdM2Of1F3AAknW0AJpwN6IgEPAEaANaMlcbmZdl7KRBuAfAb+v//yMAJoA
AAAASUVORK5CYII=

My application doesn’t put any limitations on the size of the image being linked, so I may have to add logic to resize it to something sensible for the receiving program.  I surely don’t need a 5MB image in my XML stream!  Watch this space for updates. Finally, I need to put this converted data into the XML output.  Template tags to the rescue! In tempplatetags/filters.py:

@register.filter
def b64(url):
    import base64, urllib
    if url:
        try:
            i = urllib.urlopen(url)
            return base64.encodestring(i.read())
        except:
            return None
    return None

This tag will try to open the url and convert the contents.  Not much error checking here.  If it doesn’t work, the value of None is returned. An this is an example template file, called ucal.xml:

{% load filters %}<!--?xml version="1.0" encoding="utf-8"?-->

...

{% if e.photo_link %}{{ e.photo_link|b64 }}{% endif %}

(Note that the {% load filters %} directive is on the same line as the xml version declaration.) The b64 filter takes the supplied URL and returns the base64 encoded version.

UPDATE:

Learned that the calendar can also just take a URL to the photo as input. Oh well, at least I got to learn something new.