Introduction
OK, here is the problem, you have an image and you either want to set some EXIF tag in it or read some EXIF tag embedded in it. Solution...? well part of it has already being implemented by MS in .NET but that is just the tag number and raw data associated with it. Clearly this does not help us in any way when a user just wants to read the image comments. First you must know the tag number, then using .NET you extract that tag and then convert it. Well on the first hand it doesn't sound that bad (which if you take my word is really not bad if you are concerned with just ASCII strings) but say you want to extract ISO speed which ironically is in rational number format or other data types that require conversions, then you will agree that not only it's bad it can be sometimes stupid. If you are a person like me you will scratch your head first and think why are they trying to trick us by embedding the data like that? They could have easily done that in other simpler formats, but guess what? It's already done and you are the lucky one who is going to do all the decoding. What you have read in the previous lines were part of my emotions, when I set out to make an EXIF control for this website.
I will continue to update this control on my website so in case you are looking at this article in 2006 (and provided humans don't start WW3) there are some good chances that you will find the latest version there.
Background
Basic match knowledge, along with basic C# knowledge and idea about the Bitmap
class. Oh yes 1 Brain (but it's optional).
Using the code
EXIFextractor is a very lightweight class, which you can just pass in your Bitmap
as a reference and this class will use it. The bitmap won't be modified unless you call the setTag
function to change a specific tag. It will be your job to store/save the bitmap once you have added/modified a tag.
Here is a sample code that shows you how to dump all the tags on a console.
System.Drawing.Bitmap bmp =
new System.Drawing.Bitmap("F:\\DSCI0006.JPG");
Goheer.EXIF.EXIFextractor er =
new Goheer.EXIF.EXIFextractor(ref bmp,"\n");
Console.Write(er);
er.setTag(0x13B,"http://www.goheer.com");
If you want to get individual items such as artist name. Please keep in mind that this can return null
for EXIF properties that are not present in the system, so it's a right thing to check for null
values before doing any operation.
Console.Write(er["Equip Make"]);
You can also use enumerator like foreach
and get all the properties one by one. Here a point worth mentioning is that the data is returned in the form of System.Web.UI.Pair
object.
Goheer.EXIF.EXIFextractor er =
new Goheer.EXIF.EXIFextractor(ref bmp,"");
foreach(System.Web.UI.Pair s in er )
{
Console.Write(s.First+" " + s.Second +"\n");
}
Here is the list of properties that you can get using this method, all the values returned in this case will be converted to string values.
</SUMMARY>
Here is how the class works. We take the PropertyItem
array provided by .NET and then convert it to human readable form according to the EXIF standards. I am chopping off the extra details here you can see them in the code provided. Basically there are 6 types of data types that are normally embedded in an image. We take each one and treat them differently. Sometimes in a specific data type we have to do extra conversion for a specific tag (i.e. iso), we have to perform specific calculations on the data after which we will get the human readable form. There are many such conversions done in this loop which again I have removed on purpose.
System.Drawing.Imaging.PropertyItem [] y =
bmp.PropertyItems;
foreach(System.Drawing.Imaging.PropertyItem p in y)
{
if( p.Type == 0x1 )
{
}
else if( p.Type == 0x2 )
{
}
else if( p.Type == 0x3 )
{
}
else if( p.Type == 0x4 )
{
}
else if( p.Type == 0x5 )
{
}
else if( p.Type == 0x7 )
{
}
}
As you can see the basic concept is straight but the things you have to do for data conversion kills you.
Last thing to remember is that this code is provided as it is, if it fortunately destroys all of your precious image collection then no one is to be blamed except you ;).
Points of interest
If you want to see the scalability of this control then you should definitely visit this site. On this site when a user uploads a picture all the data is automatically extracted from the image, along with that the image is checked for duplicates if someone else has uploaded that same image or not. Then in the next stage thumbnail images are created, so basically you can say that this site works on its own.
History
I wrote my first article on how to display screensaver on both screens of a dual monitor. If any of you guys have free time then do check it out and give me suggestions/comments about that too. It's called GxTS.