Flex: FaviconGrabber – Remote icon fetch

This application FaviconGrabber loads a remote icon from a specified url.

Sample App

This was developed to test out the technique of pulling a favicon from a remote url for display in a Flex application. The application I had in mind was the Social Graph Browser where the favicon for a results urls would be embedded into the graph nodes (where available). I thought that pulling favicon files from a site would be simple to do but it turned out to be a bit of an adventure.

Firstly you can’t use HTTPService to get the icon directly. If you run the app locally it will fetch the data but since the service only deals with xml and text it will throw a ‘decode’ error. I.e the binary data in the icon contains bytes which are not accepted by the service. What’s more if you deploy the request to the web site it will simply throw a security error since this is an illegal type of operation unless the remote site has a crossdomain.xml file.

My final recourse was to write a Python cgi script to fetch the icon and then encode it into Base64. This is an encoding scheme which lets you embed binary data into xml. You can see the script bundled into the source.

Okay, so I had my Base64 encoded data. I can use HTTPService to execute the script and get the data back. Flex has a built in class Base64Decoder which you can use to decode the result of the proxy query. i.e.

var decoder:Base64Decoder = new Base64Decoder();
var rawData:ByteArray = decoder.flush();

Having got the data I realised that I had no means to display it. The ICO format is not a format that AS3 recognises.

A bit of a rummage around the internet and I discovered that flexlib has an IconLoader class which will display ICO format files. The problem is that it will only do it from an embedded resource or local url. It doesn’t take raw data.

This was already starting to become a pain in the backside for what was supposed to be a ‘nice to have’ feature of an application that was pretty esoteric to begin with. Still I soldiered on.

After modifying the IconLoader class to take raw data I got the Facebook icon working. Ah that sweet feeling of success how fleeting it is! The next icon I tried was from google. Didn’t work. Eh! Tracing through the code in debug mode it turned out that IconLoader didn’t support that particular icon format (8 bits per pixel [bpp] as it turns out). In fact all it supports is the easy peasy 32 bits per pixel which handily enough matches the AS3 bitmap format exactly. Since most of the favicons I subsequently looked at were either 8bpp or 4bpp I was well and truly stuffed.

There was nothing for it but to write the code for loading the other icon types into the control. This was a bit of work and I am now on familiar terms with Microsoft bitmap formats. More so than I wanted to be. I will be submitting this code back into flexlib so that others can use it. The extended component is bundled with the source for FaviconGrabber. It now supports 4bpp, 8bpp, 24bpp and of course 32bpp Windows icon formats.

Application here.

Source code here.

All that and I still haven’t incorporated it on the graph! That’s my next task.

– Fixed bug in loading multiple icons from the same ICO image.
– Altered FaviconGrabber to accept any url. You don’t have to stick ‘favicon.ico’ onto the end. Just put in the url and it will attempt to get the associated favicon.


4 Responses to “Flex: FaviconGrabber – Remote icon fetch”

  1. Doug McCune on March 6th, 2008 2:50 am

    Shoot off an email to the flexlib list, pointing back to this blog, just so I don’t lose the link 🙂 I’ll take a look at your code in a few days and add it into flexlib and add you as a contributor. Thanks for doing the hard work 😛

    And send me an email too so I have your contact info. Cool.


  2. Administrator on March 6th, 2008 9:55 am

    Thanks Doug. Will do.

  3. Chad on April 22nd, 2008 10:21 pm

    I must say that some impressive hackery! Very nice work!

  4. Jeff - House of Treasures on May 1st, 2008 3:24 pm

    I agree with Chad as this is fantastic. Thanks a bunch for sharing!