Data URI’s

Inlining images in base64 encoding is a pretty neat trick. Not all that useful in most scenarios, since http connections are most likely all persistent these days and browsers tend to cache image resources. Still, I find this approach interesting when you want to limit the number of files you deliver or you can’t really reference external resources at all.

The basic technique involves two things: encoding your image in base64 format and inlining the resulting string into your img tag. Here is an example:

[code lang=”html” gutter=”false” toolbar=”false” wraplines=”true”]

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABICAMAAAA+uQBRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABJQTFRF////zMzMmZmZZmZmMzMzAAAA8496aQAABHBJREFUeNrsWNGW6jAIzAD9/1++DCRNWrVtovt2czyuusokMAyEUu4XRIDyV0t0y2Wm6kA/RYIYLbtZEVXbOtQvzoSwqDJ6SkCghmTqn61uPRyjdZfgEYQeav9HvtVNl7du3bq4R7j78xe5ickToJq3wZo7myd4Z96/OglgNYAPyOW7QJkGGCh5SRNnl0lsaBKA+5KRJm9hSF6tJ54kK+ovGdgRZnQarNNrGqC4ucEUYbYjDM0b+tdnAez1Jzgk8ZbO3wFmc0A/7Wn3mR49Oi1tl6njBrfje5vO4u0q+X8AwFS75MDXAB6Ego+pfAKQBa1jlDFq3RXJVgAiykFHRvss9yeAFbWOKHuCQmhLTpw6Asi0FLUohwKIv8AVABNjEUDDPW+yqAP4EU2XAOgaYS3mCYp+OoGYA8xLUQZBUIXHeWkhEzgqiYu4+v4XxLRF2QXTC7o7wLasQrXeJ4BXfO+RTNYA/Fcadt1a7JFHImvRAJyc6hGQsgigEWVkOVEGRHcRjDRUYdnLirnUKzp7MkWN1iVzwQYA52fWnAUpyiCkWCSSJJh2gI09V/kKQGpX6n+9/IaZAUBLZRXWACLK4SsSJoWj6ZokwBdq3aLc3yjtoOraEcCWOtO0cv6gFuMgEx7VppsoH68gThzpAN0+3l+HuFQuC6McAbU+jQBnIUL0+O5LQ6wrhLNvI7HiM+wAetyFJzYvPVBow1VcRRkvzaiVEeDQ3oC1od8t9pdXUT7XZKCMANU+2uptNuJiFGEwverO39d91ErNJBRPuB2+FgqECIe7/H6lt/fLwx1wB9C4Y/LSs3sy+xAuXu6CDv6QJ1e1I0YCYP+CDC29ZTTSe2aXUf6IkeWuM1VrDOqVRKzRlwLwLM2PGIiLn45wEWPJNopcShb52eSxjnQMlKzVwRJ3ODcL1gZkxaPNxHdQnek4oPv9I6Fy52xs2F3ECRBh7eG2SSUcblPpZETBwUZ/BwBv/zFpoNNwS6KLc7Dwu6GoB/D2hW8zcyhGbBUU9oREL7mBOtxBiE8WHH7qKBp9lG9fsnnWonO2JZKo3tVJG43QGpdGVWJofOfsQ/xJ7lmaAxbaLW3O4m6VPEHUfamcAiWaRGU3o7zAuH/uSaR1uiXDaWugCbzf071oS3T7sXWJAzHY96V5V76uOY2tnGU0AJekIhF/tkz3g5R2NsibqRDSQYhE6gDuIsvJxr31GspSpNf21Edk7jpXJB47QAkC3M/w0GZmtZEehNIRNEcVfM0S6pANQJ/4JQwJxlqX+d7GFJR3iwkUAYzZq/v88WmajuEF2zkSNV0UucuUCgCwtWSVnMtVHSpm3ge4vwrg2Ym0GsUy1qwUtB80VQsArdR0005MniCVdKljRNJIgOp2L4lSG0cCuWm1L+a9Imm9ecVFOJRSUicbj74YJbPCShQkrdqbNDIOlOUHQ3HuVtkOZIlVq4XrZ7P20AjZ3vTXvxrmZ3tbq8lfrKDIYcr+4+U+wkICTRDVVKX85RKU/+tl/RNgAMFwGP4bvg4lAAAAAElFTkSuQmCC">

[/code]

The tag’s src=”data:…” bit is called the Data URI scheme and has been around for a while and is now implemented in most browsers.

The encoding bit is easy and can be done in most frameworks. I spend a lot of time in grails so to do this in groovy you just do this:

[code lang=”groovy” gutter=”false” toolbar=”false”]
f = new File("tcsmall.png")
b = f.readBytes()
b.encodeBase64().toString()
[/code]

This approach has some overhead. Base64 encoding only uses 62 or 64 characters of a possible 256 in a byte so overall bytes going over the wire will be more. You would normally only use this for very small images.

For the life of me, I don’t know why browsers don’t use this technique when you save web pages locally. My gut says loading the base64 encoded versions from disk is negligible. If browsers used this, they could save an entire image-rich web page into a single html page. Instead, what browsers do is they write a single html file and all image /css resources in a directory alongside the html. References to images are all then re-pointed to the files in this directory. Yuck. Maybe browsers do this specifically so you can have the images as files for easy access. Who knows.

Anyway, I see some browsers (like Chrome) use this feature for things like “file/folder” icons when viewing ftp sites. Unless the browser is using OS native calls to render these directly, it needs to do something if it renders html to display this kind of interface. In the case of Chrome, it uses data uri’s and plain html to show a ftp user interface. I suppose a browser could reference files on your local hard drive, but seeing links in “view source” like: file:///C:/Users/ncodignotto/AppData/Local/Google/Chrome/Application/icons/folder.png, well, that shit just seems wrong.