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]
    ⇓ 21 comments Stekletz

    Hi Jacob! I think i found a bug in your binaryajax.js file, on line 172:

    'this.binaryResponse = new BinaryFile(this.responseBody, iDataOffset, iDataLen);'

    must be like

    'this.binaryResponse = new BinaryFile(oHTTP.responseBody, iDataOffset, iDataLen);'

    You see, i use `oHTTP` instead of `this`, coz `this` not working in IE6.

    If you open your imageinfo test page at http://www.nihilogic.dk/labs/imageinfo/ in IE6, you should see that is not working and get an error.

    Best regards & sorry for my english. ;)

    August 26, 2008 at 12:30 AM
    Jacob Seidelin

    Thanks Stekletz. Fixed.

    August 26, 2008 at 6:56 AM
    jesusvld

    Excelente utilidad, me servirá mucho para futuros proyectos.
    Gracias !!

    August 26, 2008 at 4:37 PM
    Anonymous

    how can I mod this script to return the raw binary data itself? I really need to get all the data not just the info.

    thanks
    -evan

    September 5, 2008 at 8:19 AM
    Jacob Seidelin

    The file binaryajax.js takes care of all the raw data handling, take a look at how the image metadata reader calls BinaryAjax() and the accesses the data.

    September 16, 2008 at 10:01 AM
    Chris

    Sorry to bother you again but i'm stuck. :(

    you said the exif.js file is optional but when I remove it from my page javascript returns the error "EXIF Undefined".

    Anyway to solve this?

    var file = "image.jpeg";
    function mycallback()
    {
    var info = ImageInfo.getAllFields(file);

    alert(info["byteSize"]);
    }

    January 23, 2009 at 8:44 PM
    Jacob Seidelin

    Ah, you're right. It's fixed now, you should be able to use it without the exif code now.

    January 24, 2009 at 2:42 AM
    Chris

    Thanks.

    I’m trying to change the “readJPEGInfo(data)” function in the imageinfo.js to use the EXIF Width/Height instead. The reason being is that its 3x faster for what I need.

    I think I narrowed it down to this code…

    while (offset < len) {
    var marker = data.getShortAt(offset, true);
    offset += 2;
    if (marker == 0xFFC0) {
    h = data.getShortAt(offset + 3, true);
    w = data.getShortAt(offset + 5, true);
    comps = data.getByteAt(offset + 7, true)
    break;
    } else {
    offset += data.getShortAt(offset, true)
    }

    I’m tying to change the above function to use the bytes (offset/pointer?) from the width/height in the EXIF.Tags but I’m not sure how to convert it or use it so the above function will work with it.

    EXIF.Tags = {0xA002 : "PixelXDimension", 0xA003 : "PixelYDimension"};

    I have spent so much time with this trying to figure it out and I would be grateful for your help. Thanks.

    January 25, 2009 at 11:37 PM
    Gerry Grmano

    Jacob,
    I searched days before finding your method. Thanks much. I see that code uses XMLHttp Request. Is there any way to extract same jpeg image data from images on other domains - as best I can tell, XHR requests don't work cross domain.
    Gerry

    March 29, 2009 at 5:59 PM
    Jacob Seidelin

    @Gerry: Not that I know of, no. You're stuck with XHR and its cross-domain limitations.

    March 29, 2009 at 9:55 PM
    James

    Hi. I have a problem here. I tried the codes in binaryajax.js and exif.js but it's not working I don't know why. I just copied what's in here. It just displays undefined. Does anybody know the solution? I really need the codes to work badly. This is for our school project. Even if just the extraction of the date the picture was created would be very helpful. Please advise on what to do. I also included the codes I use. Thank you very much.

    head -- (I removed the angled bracket because they won't accept it)
    script type="text/javascript" src = "exif.js"
    /script
    script type = "text/javascript" src = "binaryajax.js"
    /script
    /head

    img src = "Bush-dog.jpg" exif="true" id = "image"

    script
    var Img = document.getElementById("image");
    alert(EXIF.getTag(Img.exifdata, "Make") + " " + EXIF.getTag(Img, "Model"));
    /script

    March 31, 2009 at 6:36 AM
    Anonymous

    Hi. When I run () code, what comes out is:
    All info about this file: ({format:"JPEG", version:"", width:129, height:97, bpp:24, alpha:false, exif:{ExifIFDPointer:2110, undefined:[28, 234, 0, 0, 0, 8, 0, 0 ... (many zeros!) ... 0, 0]}, mimeType:"image/jpeg", byteSize:"10446"})
    Any ideas why EXIF info is not coming out right? ... :S
    Manuel

    October 16, 2009 at 4:17 PM
    Beben

    its a cool ...

    January 19, 2010 at 8:14 AM
    Anonymous

    Hi, your library is really useful. I use the code on my demo server and it works fine. but when i uploaded this code on to a client's server it won't work as it should. i'm not sure if there's any needs for server configuration or any limitation on some server?

    February 14, 2010 at 9:39 PM
    Devvyn Murphy

    This is frickin' fantastic. I searched for this answer for a long time, and was on the verge of giving up. You're a saviour! Thanks so much for sharing this!

    I've used it to detect alpha in PNGs and handle CSS formatting differently depending on whether the image is therefore assumed to have a box shape or if it should just show the background through from the page.

    May 12, 2010 at 6:45 AM
    Anonymous

    Спасибо ОГРОМНОЕ!(Thanks)

    May 18, 2010 at 12:35 PM
    Tiller

    Awesome work! With my limited JS knowledge (I'm mainly an Actionscript guy), I was still able to get this working in about 20 minutes or so.

    Quick Question: I know this isn't set up to handle XMP Metadata, but is there a way to do that at all? I've been scouring the internet for the past week or so trying to find a way to extract XMP Metadata with JS, AS, PHP, etc to no avail.

    February 10, 2011 at 5:23 PM
    SaKeL

    Hi i just want to ask how to point to images what are in other DIR... for example ("../images/"+file) ..how can i do that plz ?

    April 24, 2012 at 5:10 AM
    Suresh Kumar Patel Thota

    sry am nit getting imageinfo.js file ,please let me know right location to search

    September 14, 2012 at 1:28 AM
    Артем

    Thanks, it helped me a lot. Really appreciate your work. Is it still being developed?

    March 20, 2013 at 9:01 AM
    David Robinson

    Have you added any further logic for EXIF metadata in PNG files?
    Thanks, David

    February 21, 2014 at 5:12 AM
    Post a Comment