Reading JPEG Exif data with ColdFusion and Java
Exif data, a brief intro.
Exif data (and IPTC) is information about the image that is stored in JPEG image files. This information can be created by a digital camera or added to the image with programs such as PhotoShop.
Data such as the image size, who took the shot, where it was taken, image title, width and height, copyright material etc can be stored along with the image.
The advantage of gaining access to this data is that information about the image can be displayed along with the image, on the fly, without having to enter and store it in a separate place: in a database or hard coded along with the image display.
Exif Java Class.
Looking at this problem, retrieving the data from a JPEG file, when having to code it I thought there is no way I am going to be able to learn about the layout of Exif data and play with extracting it from a binary file (I only had two days to come up with a solution, excuses I know but...).
So Java to the rescue!
After a little Google I found an open source Java class that does the job perfectly from this bloke:
http://www.drewnoakes.com/code/exif/ there is a lot of data here about the class if you are interested.
ColdFusion to Java.
To get ColdFusion to talk to the Java class and vice versa I have written a separate class, in the
downloadable jar file (119kb), providing methods to return the correct data, so you don't have to play with the Java side. As this is Easy CFM I will not go into the Java here.
Hooking it all Together - Registering the Class Path
Download the Java .jar file from
here (119kb).
Here is a demo image if you need it:
tester image
Now that we have jar file that does what we want we need to shoe horn it into ColdFusion.
Save the downloaded CFreadExif.jar file in a directory on your server under the ColdFusion directory structure.
For me it is in c:\CfusionMX\wwwroot\javaClasses
Now we need to register the path with the server so the class can be found, follow the steps below.
- Go to the CF administrator and login
- Click Java and JVM from the menu. fig 001
- Check that the Java Virtual Machine Path is set fig 002
- Then in the middle of the page, in the text box below Class Path enter the directory, where you saved the downloaded .jar file. You do not need to put the name of the .jar file just the directory it is sitting in. fig 003

fig 001

fig 002

fig 003
There is one thing I don't like about adding Java class paths you need to restart the server once one is added.
So restart the server to register the path. (if you have problems stop and then start the service instead of restart)
(If you do not have access to the administrator you should be able to add classes through your host's server control panel, if that is how they work. Most hosts allow for the addition of tags or classes speak to your admin.)
Calling the Class from ColdFusion.
Now we should have the Java class ready for use by ColdFusion.
First we need to kick start the Java object and assign it to a variable so that it can be called.
<cfscript>
<!--- first create the java object --->
exifReader = createObject("java"," com.drew.imaging.coldfusion.CFreadExif");
<!--- call the init function to get it started --->
exifReader.init();
<!--- call the method in the java object that loads an image for reading --->
exifReader.loadImage('C:\CFusionMX\wwwroot\testing\graphics\ testerImage.jpg');
</cfscript>
What we did here was to:
- Call the wrapper class that I wrote, a class called CfreadExif, stored in the .jar file
- The wrapper class is stored in the directory com\drew\imaging\coldfusion which is the structure in the .jar file.
- Then we call init() to kick start the object we have created.
- Then we load the image into the class so it can read the data.
The path, in the loadImage() method call, needs to be an absolute path on the server to your image. Mine, as you can see, is in a folder called testing\graphics in the ColdFusion webroot.
Now we have the object, and it has read an image, we can dump it out to see what we have.
<cfdump var="#exifReader#">
Running this cfdump code should give you something like below. But if you get a
null pointer error from ColdFusion check your path to the image. The null pointer is saying it cannot find any data because it can't find the image to read any data.
object of com.drew.imaging.coldfusion.CFreadExif
|
Methods |
getCountry (returns java.lang.String) getDescription (returns java.lang.String) loadImage (returns void) getArtist (returns java.lang.String) getCopyright (returns java.lang.String) getMakeDate (returns java.lang.String) getImgWidth (returns java.lang.String) getImgHeight (returns java.lang.String) getReportTitle (returns java.lang.String) getCity (returns java.lang.String) getPhotoID (returns java.lang.String) getPlace (returns java.lang.String) getAllData (returns java.util.ArrayList) getAllMethods (returns java.lang.String) hashCode (returns int) getClass (returns java.lang.Class) wait (returns void) wait (returns void) wait (returns void) equals (returns boolean) notify (returns void) notifyAll (returns void) toString (returns java.lang.String)
|
imageToRead |
C:\CFusionMX\wwwroot\testing\graphics\testerImage.jpg
|
desc |
[undefined value]
|
imageFile |
[undefined value]
|
exifMeta |
class com.drew.metadata.Metadata
|
exifDirectory |
class com.drew.metadata.Directory
|
iptcDirectory |
class com.drew.metadata.Directory
|
As you can see there are a number of methods to call. All the getBlahBlah() methods return data contained in the image.
You can call any of the methods in this way:
<cfoutput>
<!--- call the object.then the method --->
#exifReader.getDescription()#
</cfoutput>
The above will return the description found in the JPEG file, if one exists.
<cfoutput>
#exifReader.getArtist()# <!--- gives you the photographer --->
#exifReader.getMakeDate()# <!--- date shot --->
#exifReader.getImgWidth()# <!--- image width --->
#exifReader.getReportTitle()# <!--- image title --->
<!--- And so on. --->
</cfoutput>
Writing this:
<cfoutput>
#exifReader.getAllMethods()#
</cfoutput>
Will output descriptions of all the getBlahBlah() methods so you can see what you might want.
All the getBlahBlah() methods return strings apart from one: the getAllData() method, which returns an array of all the data that can be found in the JPEG file.
You can dump it to see what information is in the image, what might differ from the image I have used:
<cfdump var="#exifReader.getAllData()#">
The above dump code will give you a large array, you may have data such as camera make, model, and loads of stuff in there. You can then access an individual bit of data that you fancy like this:
<cfset arData =exifReader.getAllData()>
<cfoutput>
#arData[1]#
</cfoutput>
The above will give you the first row of data.
Summary.
I hope you find this useful all the thanks needs to go to the man who wrote the Exif Java class; Mr Drew Noakes. All I have done here is to demonstrate a technique for utilising high powered Java classes in your ColdFusion applications. It makes CF 10 times more powerful than without.
If anyone is interested I can write another tutorial describing how to write the Java wrapper to open up a Java class for ColdFusion use.