Most of the digital cameras use Exif file format to store images and through this format tons of information is available so that each software that deals with images can show relevant data loading few bytes.
The nice thing is that in the first 64 kbytes of an image all the information, thumbnail included, are stored in separate and well organized image file directories (IFDs), this is the reason why you don’t need to load a complete image to show it’s preview (if images are smaller than 64kbytes you can get anyway the information and there is no need to close the stream of data).
There are already some resources about exif data reading in ActionScript, you can get some great examples here:
I wrote my own solution because the first one load all the image before starting to parse the data, because the second one created me some issues with a Motorola image and because I get also information for exif 1.1 data.
What I’m missing and I would like to improve is the visualization of thumbnails stored not with the JPG information and the visualization of GPS information that I already get but are not shown properly.
In order to avoid the issues I have had I would like to spent few words before getting you to the source code.
First of all in order to understand the format I really started to read the specification you can get here http://www.exif.org/Exif2-2.PDF. I know that it may not seem the most amazing piece of paper to read but was the only way to put in place a solution with all the comments needed to make people able to extend and improve it.
My second step was to find a good software able to read exif data in order to make a comparison between the information recovered from the Exif class I created and the ones recovered from a professional software, I get ACDSEE (http://www.acdsee.com/).
The third step was to get a lot of sample images and thankfully the exif official web site has a lot of them (by the way I embedded the images also in the sample application I did) available here http://www.exif.org/samples.html.
The last step was to get an hexadecimal reader to really parse and count the raw data I was going to play with, on Mac I found 0xED (http://www.suavetech.com/0xed/0xed.html), on Windows I get Hex Workshop (http://www.hexworkshop.com/).
Before starting to write down my solution I studied how other people implemented working solutions in other languages, two of the most inspiring for me were this one in Java http://www.java2s.com/Open-Source/Java-Document/Web-Server/Jigsaw/org.w3c.tools.jpeg.htm and this one http://mediachest.sourceforge.net/mediautil/javadocs/mediautil/image/jpeg/package-summary.html always written in Java.
Let’s start with some clarifications …
The Exif file format is based on the JPEG file format. Exif inserts some of image / digital camera information and thumbnail image to JPEG in conformity to JPEG specification. Therefore you can view Exif formatted image files by JPEG compliant Internet browser / Picture viewer / Photo retouch software etc. as normal JPEG image files.
Every JPEG file starts from binary value ’0xFFD8′, ends with binary value ’0xFFD9′. There are several binary 0xFFXX data in JPEG data, they are known as ‘Marker’, and it starts a new part of JPEG information. 0xFFD8 means SOI (Start of image), 0xFFD9 means EOI (End of image). These two special Markers have no data following, the other markers have data with it.
The marker 0xFFE0~0xFFEF is named ‘Application Marker’, not necessary for decoding JPEG image. They are used by user application. For example, older olympus / canon / casio / agfa digital camera use JFIF (JPEG File Interchange Format) for storing images. JFIF uses APP0 (0xFFE0) marker for inserting digital camera configuration data and thumbnail image.
Exif format contains a thumbnail of the image (except Ricoh RDC-300Z). Usually it is located next to the IFD1. There are 3 formats for thumbnails; JPEG format (JPEG uses YCbCr), RGB TIFF format, YCbCr TIFF format. It seems that JPEG format and 160×120 pixels of size are recommended thumbnail format for Exif2.1 or later. By the DCF specification, thumbnail image MUST use JPEG format and image size is fixed to 160×120 pixels. If the value of Compression (0×0103) Tag in IFD1 is ’6′, thumbnail image format is JPEG. Most of Exif image uses JPEG format for thumbnail. In that case, you can get offset of thumbnail from JpegIFOffset (0×0201) Tag in IFD1, size of thumbnail from JpegIFByteCount (0×0202) Tag. Data format is ordinary JPEG format, starts from 0xFFD8 and ends by 0xFFD9.
The following terms and notation are used as follows in the exif standard:
• “Tag” is used as a synonym of “field”,
• “.H” appended to a numerical value means it is hexadecimal notation,
• Unless otherwise indicated, other numerical values are given in decimal notation,
• The initial IFD in a file is the “0th IFD,” with the next IFD being called the 1st IFD
• The term Primary image refers to main image data
• The term Thumbnail indicates a small image used to index the primary image
• Exif is an abbreviation of Exchangeable image file format, used here as the general term for this standard and earlier versions of this standard
The main class of this solution is named Exif and contains all the exif tag uint values as class constants and a bunch of methods used to expose the data to the end user (i.g. the developer that use it in a project) and other methods to parse the information
The class extends the URLStream class so what you have to do in order to use it is creating and instance and load a valid URLRequest through it.
The events dispatched from the Exif class you have to aware of are
The first one is fired when the data are parsed completely, the second one indicates that a serious error happened (i.g, not a valid jpg, not valid exif data, etc.), the third one can be used to handle not serious errors (i.g. a tag is not properly recorded), the fourth one indicates that the exif data have been completely parsed and the last one is the event that inform you that the thumbnail is ready.
The public API can be used in order to get the thumbnail, the error logs, all the IFD recovered from the class and the amount of data loaded in order to parse the exif data.
The class usage is quite simple but the logic inside is a little bit more complex, in fact the core consists of two methods
The first one is the one that read all the entries (i.g. tags) stored in an IFD and that collaborates with the parseTag method in order to read the data as defined in the exif specification and with the Naming class used to handle a lot of situations like flash, orientation, etc. making these values human readable.
The following types are used in Exif (you see this types recovered in the first lines of the exploreEntries method):
• 1 = BYTE An 8-bit unsigned integer.,
• 2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL.,
• 3 = SHORT A 16-bit (2-byte) unsigned integer,
• 4 = LONG A 32-bit (4-byte) unsigned integer,
• 5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the
• 7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition,
• 9 = SLONG A 32-bit (4-byte) signed integer (2′s complement notation),
• 10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the
The Naming class can be passed to the Exif class in the constructor so that you can easily create your localized version of exif reader overriding the methods that initialize some arrays used to store values for the flash, the orientation, the exposure, etc.
Each time and IFD is found in the file the exif class create an IFD instance so that you can easily keep track of them and create customized helper classes to parse all these information, each time a valid exif tag is defined an instance of the ExfTag class is created, thorugh this class you can easily know the name and the value of a tag, use the public getTagValue method passing as an argument one of the 130 and more constants defined in the Exif class.
All these classes are available inside nabiro, the open source ActionScript library made up of a lot of components created during our daily job published here http://agile.gnstudio.com/nabiro.
At the end of this post you find the sample application with the source code include, byt the way in order to use this tool you only need to instantiate the class, define a couple of event listeners and load a file
exif = new Exif();
The three event listeners populate a text area with the error log message, display a list of available data and load the image, so you can easily get this result
Download here the source and the application and please feel free to use it as you want but please provide me as much as possible your feedback.