Check out my
new book!
HTML5 Games book
ImageInfo - read image metadata with JavaScript A small JavaScript library capable of reading metadata (format, dimensions, etc) from image files.

Trying to squeeze out the last drops of binary juice before moving on to something else, here's a small library much like the ID3 reader but for images. It works pretty much the same as the ID3 library and as you'll see below, the code to use it is also very similar.


It tries to detect the format of the image file and then reads the header and pulls out information about dimensions and color depth among other things. If the EXIF data library is included, it will also gather any EXIF info from JPEG files.

Example usage:
<!-- include these files -->
<script type="text/javascript" src="../binaryajax/binaryajax.js"></script>
<script type="text/javascript" src="imageinfo.js" ></script>
<!-- optionally include exif.js for Exif support -->
<script type="text/javascript" src="../exif/exif.js" ></script>

And then a bit of JavaScript:

// URL of the image (must be on the same domain!)
var file = "prettypicture.jpg";

// define your own callback function
function mycallback() {
   // either call the ImageInfo.getAllFields([file]) function which returns an object holding all the info
   alert(
       "All info about this file: " + ImageInfo.getAllFields(file).toSource()
   );

   // or call ImageInfo.getField([file], [field]) to get a specific field
   alert(
       "Format: " + ImageInfo.getField(file, "format") + ", dimensions : " + ImageInfo.getField(file, "width") + "x" + ImageInfo.getField(file, "height")
   );
}

// finally, load the data
ImageInfo.loadInfo(file, mycallback);


File formats supported are JPEG, PNG, GIF and BMP.

It was somewhat inspired the IMG2JSON AppEngine application by Adam Burnister so the field names have similar names. Calling the getAllInfo() function will get you an image info object containing the following fields:


  • format (one of "JPEG", "PNG", "GIF" or "BMP")
  • version (currently only used for GIF, ie. "89a")
  • width (width of image in pixels)
  • height (height of image in pixels)
  • bpp (bits per pixel, ie. 8, 16, 24, etc)
  • alpha (true if alpha channel is present, only for PNGs)
  • mimeType (the mime type sent by the server)
  • byteSize (the image size in bytes as reported by the server)
  • exif (an object containing EXIF tag data, if present. Only for JPEGs)


  • These are also the fieldnames used in the getField() function.

    I might try to include more format specific information later (like color tables for indexed GIFs and PNGs, number of frames in animated GIFs and so on).

    Since the header information is usually only a very small portion of the image file, there's an option to only request a number of bytes from the beginning of the file. By setting ImageInfo.useRanges = true and ImageInfo.range = <n>, only the first <n> bytes will be downloaded. However, since the position of the header information in JPEG files isn't fixed (neither is the size of any EXIF data), this has been left as an option. If you're not using it with JPEG files or if you know your JPEGs don't have embedded thumbnails, you should be safe to set it to only get the first few KBs or so.

    See it in action here: http://www.nihilogic.dk/labs/imageinfo/

    Download the code here: imageinfo.zip [9 KB]
    Read more...
    Read ID3 tags with JavaScript A small JavaScript library capable of reading ID3 (v1) tags from MP3 files.

    I figured I'd try to put the binary Ajax code to some other use than the EXIF data library, and a simple project seemed to be the ID3 tags used to store artist, title, etc. in MP3's. For now, it's only capable of reading (the rather lacking) ID3v1 tags since these are very simple compared to the more fleshed out and robust ID3v2 tags. Maybe I'll try to add support for the v2 tags later.

    The script tries to only requesting partial data by using the Range request header if ranges are supported. This means we only have to download the actual tag data but also that we have to make a HEAD request first to get the file size and to ensure ranges are actually supported.

    It's rather simple to use:

    Two JS files are needed:
    <script type="text/javascript" src="../binaryajax/binaryajax.js" ></script>
    <script type="text/javascript" src="id3.js" ></script>
    

    And a bit of JavaScript:
    // URL of the mp3 file (must be on the same domain!)
    var file = "mymusicfile.mp3";
    
    // define your own callback function
    function mycallback() {
     // either call the ID3.getAllTags([file]) function which returns an object holding all the tags
     alert(
      "All tags in this file: " + ID3.getAllTags(file).toSource()
     );
    
     // or call ID3.getTag([file], [tag]) to get a specific tag
     alert(
      "Title: " + ID3.getTag(file, "title") + " by artist: " + ID3.getTag(file, "artist")
     );
    }
    
    ID3.loadTags(file, mycallback);
    
    

    Tags available are: artist, title, album, year, album, comment, genre

    As with the EXIF reader, it does not work with Opera since I still haven't found a way to access binary data with that browser.

    Check out a demo here: http://www.nihilogic.dk/labs/id3/

    Download the source code here: id3.zip [3.17 KB]
    Read more...
    EXIF GPS info, Google Maps
    Support for the GPS tags has now been added to the JavaScript EXIF data reader. I've whipped up a small example, a mini-gallery of sorts, where the GPS coordinates are read from the photos and then a small Google map shows you where it was taken. Check it out here. It is also easier now to load the EXIF data when you need it rather than have everything loaded on page-load.
    Read more...
    Read EXIF data with Javascript
    Update: I've also posted a jQuery plugin that uses this library. An example of using GPS tags with Google maps has also been posted here.

    Inspired by a comment on Ajaxian, I killed another afternoon or two making a small EXIF reader library capable of reading EXIF info from JPEG images, figuring I would at least learn a bit about EXIF information and the JPEG (and TIFF) image formats.

    Before we start, a small disclaimer. I'm somewhat of a dork when it comes to cameras and photography and my digital camera always laughs at me after I take a picture. So I won't go into details about the actual data, since I don't even know what half of these EXIF tags mean.

    So, there are two parts to the problem. First step is to get access to the raw binary data of the JPEG. Now, while it's easy to get to the pixel data using canvas, we don't get any of the data around the actual image, and that's where the interesting parts are hidden. A while back when I first started nerding around with the idea of reading data from images (for the PNG compression and other things), I also toyed with the idea of just reading binary files raw and found that other people had already done good work on this.

    As it turns out, we can easily get access to binary data using simple Ajax techniques and we just need to do a few methods for reading bytes, integers and string at given offsets. Binary data is readily available through the responseText property in both Firefox and Safari, it seems, but both IE and Opera pretty much destroy the data. Luckily, IE provides another property on its XHR object, "responseBody" which holds the binary data, but unfortunately our access to this data is also rather limited in Javascript. A quick fix is given to us by VBScript. I shame myself and make a simple VBS function to call from our getByteAt function when using IE and now we've got binary access covered in all but Opera. If anyone knows of a way to access the data in Opera, please leave a comment.

    Second step involves a lot of reading. If you're interested, read the EXIF and TIFF specs yourself. EXIF data is basically a small TIFF file embedded within the JPEG file. Anyway, the rest is simply seeking out the relevant data portions and reading them into a Javascript structure (see exif.js).

    And the result..

    A custom attribute on an image element will now load the EXIF data when the page has loaded and make it available for scripting as follows


    <img src="DSCN0614.JPG" exif="true" id="MyPrettyImage" />




    var oImg = document.getElementById("MyPrettyImage");

    alert("I was taken by a " + EXIF.getTag(oImg, "Make") + " " + EXIF.getTag(oImg, "Model"));

    // or use the EXIF.pretty() function to put all tags in one string, one tag per line.

    alert(EXIF.pretty(oImg.exifdata));

    I've tried it on a few pictures of my own and some found on the internet and it seems to work just fine, but it needs a few checks here and there, so it might go wonky if it encounters something unexpected.
    One limitation before the end. Since we're using XHR, you can only access the data from images on your own domain.

    Check out the EXIF test page here
    Read more...