jQuery EXIF data plugin
I've never really used libraries such as jQuery or Prototype and only really know them by name. So, I decided to take a look at jQuery and found that turning something like the EXIF reader into a jQuery plugin was a matter of adding just a few lines.
Using this, you can now do something like:
and then
Now, I've still only looked at jQuery for 30 minutes or so (seems very cool, though!), so bear with me as I stumble through this field of foreign frameworks and let me know if it needs anything.
Check out the jQuery EXIF data demo here where you'll also find download links.
This was really spurred on by a comment on the image effects library, so maybe I'll see if I can turn those into plugins as well.
I've never really used libraries such as jQuery or Prototype and only really know them by name. So, I decided to take a look at jQuery and found that turning something like the EXIF reader into a jQuery plugin was a matter of adding just a few lines.
Using this, you can now do something like:
<img src="image1.jpg" id="img1" exif="true" />
<img src="image2.jpg" id="img2" exif="true" />
<img src="image3.jpg" id="img3" exif="true" />
and then
$("#img1").click(function() {
alert("Taken with a " + $(this).exif("Make") + " " + $(this).exif("Model") + " on " + $(this).exif("DateTimeOriginal"));
// exif(strTagName) returns a string with value for the tag [strTagName]
});
$("#img2").click(function() {
alert($(this).exifPretty());
// exifPretty() returns a string with all tags and values, one tag per line
});
$("#img3").click(function() {
alert($(this).exifAll());
/* exifAll() returns an object holding all tags and their values
* {
* "Make" : "NIKON",
* "Model" : "D100",
* ...
* }
*/
});
Now, I've still only looked at jQuery for 30 minutes or so (seems very cool, though!), so bear with me as I stumble through this field of foreign frameworks and let me know if it needs anything.
Check out the jQuery EXIF data demo here where you'll also find download links.
This was really spurred on by a comment on the image effects library, so maybe I'll see if I can turn those into plugins as well.
Hi Jacob,
November 30, 2008 1:27 PM Jacob SeidelinThis seems to by the only EXIF plugin for jQuery. Great job on leading! Unfortunatly only img1 and img2 examples work and only in Firefox. Opera and IE are alerting spaces.
I also notice this example only works on a production server. Localhost alerts spaces.
Thx
PS: Version numbers on your JS helps a lot.
-=Dan=-
Hi Dan,
November 30, 2008 11:47 PM Bill LabusThanks for the feedback. The third example is supposed to alert "[object Object]" or something like that, does it not do that?
It works fine for me in IE7. Opera doesn't work and won't work until they fix their XHR to allow access to the raw data.
I'll try to update the jQuery plugin next time I touch the EXIF code.
This looks like a great plugin, but for the life of me, I can't get it to work. I copy it to my root directory, but as soon as I even try to load it, I get an error saying "Object Expected, Line 858".
May 29, 2009 11:09 AM Jacob SeidelinSure enough, I go to line 858:
jQuery(document).ready(loadAllImages);
and when I try to right click to follow the 'jQuery' code hyperlink, it says that the link does not exist. However, I do have jquery.js in the same directory as your plugin.
Any ideas?
To anyone reading: Bill's problem was resolved (by Bill himself) and turned out to be due to the order of which the JavaScript files were loaded. Be sure to load jQuery before the EXIF files!
May 29, 2009 1:30 PM KJHolidayFirst off, thanks so much for your effort on this plug-in. It was a wonderful starting ground for me.
June 9, 2009 11:28 AM KJHolidayI modified your plug-in to load single images on demand. For example, my gallery has one single image in the middle of the screen. I use JavaScript to change the src attribute to load another image. I have a "Photo Details" link that when clicked will get the Exif data for the image currently sitting in my place holder current image slot.
One serious problem I ran into was that Firefox read all of my Exif Data almost instantly. However, IE would take sometimes 20 to 30 seconds to return the data. I started tracing it down and I found that for certain tags that contained arrays of values, it was choking IE. The biggest offender in my images from my Nikon D60 was the "MakerNote" tag. It had 1248 values.
The section of code, specifically for the "MakerNote" tag, causing the slowdown was the following from the readTagValue function:
case 7: // undefined, 8-bit byte, value depending on field
if (iNumValues == 1) {
return oFile.getByteAt(iEntryOffset + 8, bBigEnd);
} else {
var iValOffset = iNumValues > 4 ? iValueOffset : (iEntryOffset + 8);
var aVals = [];
for (var n=0;n<iNumValues;n++) {
aVals[n] = oFile.getByteAt(iValOffset + n);
}
return aVals;
}
break;
My temporary solution was to add the following check in the "readTags" function to skip certain unneeded tags:
var skippedTags = "Undefined,MakerNote,UserComment";
if (!strTag && bDebug) console.log("Unknown tag: " + oFile.getShortAt(iEntryOffset, bBigEnd));
if (skippedTags.indexOf(strTag) == -1) {
oTags[strTag] = readTagValue(oFile, iEntryOffset, iTIFFStart, iDirStart, bBigEnd);
}
I was wondering if you had any thoughts here? Is there a better way to go about this? Experienced this slowdown in IE before?
Edit: In my last comment I misquoted the amount of values in the MakerNote tag for my images. The actual amount of values is 12648 not 1248. Quite a difference.
June 9, 2009 11:39 AM Jacob Seidelin@KJHoliday: It's probably due to IE just being much slower at parsing the binary data (there's a bit of separate code for IE). I guess I haven't had any images with that many values in the array fields so that's why I haven't caught it. I'll make a note and see if I can fill the arrays in a more efficient manner but I'm not sure if it can be done. Until then you'll have to make due with your temp solution.
June 9, 2009 12:33 PM MateuHi,
June 29, 2009 9:40 AM theBrantManGreat work on this, it's nice to see images get more integrated with the web, even if the whole thing is a workaround. ;-)
I'm wondering if it would be more robust to consider an event delegation model like this article so that images added with AJAX can also be processed?
For now, is the best bet to add EXIF.getData(this); to the load() method of the newly-added image?
adéu,
Mateu
So does anyone know why this returns a blank string on localhost?? I even have an apache server set up and it will not read the correct values from the pictures.
July 27, 2009 9:16 AM Jacob SeidelinNo idea, it should work just fine on localhost. Got a link to an online example?
July 30, 2009 3:20 PM LucifixThis looks like promising plugin but it doesn't work on remote images. Does anyone have any solution for this?
August 11, 2009 4:07 AM colinHi, I hope you're still monitoring this page. I love this idea and would like to use it on my site. Any idea why it's not working on this test page in IE 8 -- but it does work when I click the images on your site. I see only empty strings coming back on my page.
October 9, 2009 8:10 AM Jacob SeidelinThanks in advance,
Colin
www.colinmitchell.net/test1/new_page_1.htm
@colin: Your image is really big (2+ MB), have you tried resizing it to something more reasonable?
October 13, 2009 2:01 AM colin@Jacob,
October 13, 2009 10:02 AM Jacob SeidelinI know, I was in a bit of a rush, sorry. Also I wanted to demo a photo straight out of the camera in case my editor (CS3) felt like stripping the exif. I've updated it...still empty strings. I've also noticed that your demo page will return empty strings in this same way, but will work correctly following a page refresh. This is on IE8.
Cheers,
Colin
Ok, I'll investigate. I know there are a few things that need to be handled differently, and I have feeling that's what causing problems.
October 13, 2009 10:23 AM AnonymousI'll look into it as soon as I can.
Unfortunately don't work on IE6 ...
December 15, 2009 5:23 AM AnonymousHi Jacob,
January 6, 2010 7:10 AM JanI noticed that it only works with files in the same folder as the html page:
WORKS:
FAILS:
Any idea how to fix this?
Thanks,
Jan
janmartin AT diy-streetview DOT org
P.S.:
blogger.com does not like the img tag.
Jacob was so nice to answer my email on how to make the plugin work without clicking the image, just automatically:
January 26, 2010 5:41 AM Anonymous$("#imgA").load(function() {
$(this).exifLoad(function() {
// exif data should now be ready...
});
}); // end load
You've done it once again! Superb article.
June 14, 2010 8:08 AM AnonymousCan anything be done to allow for updating any of the EXIF data values? Reading the data is very handy; but changing the data would be the REAL hot sauce on a plug-in like this!
August 2, 2010 8:01 AM Matt BurnsAs mentioned by janmartin above, I can't get this to work with image files that are hosted on a different server.
August 20, 2010 4:27 AM Matt BurnsHere is an example page:
http://www.mattburns.co.uk/temp/scf/simplescrape.html
Any ideas?
I asked on stackoverflow (http://stackoverflow.com/questions/3530436/extracting-jpeg-exif-information-using-jquery)
August 20, 2010 5:37 AM KashgarinnBasically, you can't use javascript to fetch files from remote servers. Makes sense. Oh well.
I'm wondering if this can be done with a html file opened as a file, and an image located in the same directory? Anyone know?
August 27, 2010 3:32 AM Anonymous- I'd also voice my opinion that having the ability to update and bake the information back into the file would be great. I'm pretty sure that's not possible with just javascript, but I wonder if there are any solutions around for that kind of image information interactivity?
Hi there, I address oneself to up your blog via Google while searching in retribution allowing for regarding gold medal grant-in-aid well-earned to the event that a generosity engage in mel‚e and your temporary looks damned stirring exchange for me
September 4, 2010 5:13 PM coreyHey Jacob (and KJHoliday). I'm using jquery to dynamically load an img src into a placeholder img tag on a page. I'm trying to use the following to load the exif data and it doesn't seem to be working. The image that loads first (extracted from the hash of my url) is the exif data i continually get back. Any thoughts on what I might be doing wrong? Click the image to retrieve the exif data.
October 8, 2010 2:27 PM Gilles$("#picContainer img").live('click',function(){ $(this).exifLoad(alert($(this).exif('ImageDescription'))); });
url: http://clients.inbluelight.com/westhill/commercial/
Great stuff Jacob. corey: trying to use this code in a slideshow, I've been wrestling for about a day with this. I thought it'd be nice to post some findings back.
November 30, 2010 4:06 AM Jacob SeidelinEXIF.getData checks, whether any data has been read for some specific img object:
if (!imageHasData(oImg)) .
Since this always evaluates to false after the first read, the exif data are never updated for dynamically changed images. The quickest possible dirty hack here is to simply remove this check. Of course, you may get unnecessary reads this way. If this is a problem performance-wise, you'll have to think of some more clever way to save and reuse any previously read data in relation to the actual images.
@Gilles: hasImageData() just checks if there's something in [img].exifdata, so you should be able to just clear that property before swapping images and loading the new data.
November 30, 2010 5:29 AM GillesJacob: thanks for the tip. Naturally, yours is the better solution. Excellent job.
December 1, 2010 2:50 AM AnonymousСпасибо понравилось ! Thanks !
December 1, 2010 3:27 PM AnonymousСпасибо за материалы! :)
December 5, 2010 10:56 PM AmaxRespect blog.nihilogic.dk
The code around here seems to have some typing error. Seems that iMarker should be compare to 224, and the iOffset += line should be before the return line.
July 14, 2011 7:42 PM ace893if (iMarker == 22400) {
if (bDebug) console.log("Found 0xFFE1 marker");
return readEXIFData(oFile, iOffset + 4, oFile.getShortAt(iOffset+2, true)-2);
iOffset += 2 + oFile.getShortAt(iOffset+2, true);
}
I'm having a hard time getting this to work on images loaded via an ajax call. It looks like there has been some discussion in previous comments about this but I'm having a hard time figuring out what to do.
November 2, 2011 8:25 AM ace893My app uploads an image using the Plupload tool. Once the UploadComplete event is fired I want to render the image on the same page using $.append(). I can get the Exif data of an uploaded image if I use your method in your blog post, so I know Plupload isn't messing the the Exif data. Below is the code that is called with the UploadComplete event is fired. Any ideas?
$("#uploader").pluploadQueue().bind("UploadComplete", function(r) {
console.debug("Files Uploaded", r);
for (var i = 0; i
");
$(".uploadedImage").ready(function(event) {
$(this).exifLoad(function(event) {
console.debug($(this).exifPretty());
})
})
}
initThumbnailInterface();
})
So my code example in my last post got butchered by the comment system.
November 2, 2011 8:30 AM lequocthai$(".uploadedImage").ready(function(event) {
$(this).exifLoad(function(event) {
console.debug($(this).exifPretty());
})
})
There's stuff in there that would seem to handle images not being fully loaded, so I have no idea why it's not firing. Have you tried it with different images? With several images on the page? That's because the code is running before the page fully loads. You need to use jQuery's "ready" function, which runs only after the DOM is loaded.
March 9, 2012 6:03 PM