Wednesday, 25 May 2011

How To Read Image Metadata In C#

Ok so lets get started, in this tutorial I will be showing you how you can extract metadata from an image file.

Ok so what is metadata?, if you already know you can skip this paragraph, if not, metadata is hidden data which can be read to determine certain features of the image. features like the model of a camera and the date and time the photo was taken.

We will be using the "System.Drawing.Imaging;
namespace for this tutorial, the reason for this is because it contains the "PropertyItem" object which enables us to read the metadata from an image file. It does this using the following four properties:

  1. ID - the ID property can contain information about the camera used to take the photo.
  2. Value - this is an array of values, the format is decided by the type property.
  3. Len - this tells us the length (in bytes) of the value property.
  4. Type - this gives us the datatype of the values in the array.


The only properties we will be taking notice of is ID and Value properties.


Step 1: loading in the image file
the first thing we need to do is load up visual studio, drag a button onto a windows form and call it 'Load'. Then we drag a PictureBox onto the form.

Double click the button to create the 'Load_Click' in form1.cs.

In form1.cs create a OpenFileDialog
obejct with the following properties as shown below:

OpenFileDialog data = new OpenFileDialog();
private void Load_Click(object sender, EventArgs e)
{
data.Title = "Open First Image File";
data.InitialDirectory = @"C:\Users\Karl\Downloads\Pictures";
data.Filter = "JPG files (*.jpg*)|*.jpg";
data.FilterIndex = 1;
data.RestoreDirectory = true;

if (data.ShowDialog() == DialogResult.OK)
{
pictureBox1.Load(data.FileName);
}
}



these properties are all very straight forward but ill explain them just in case.

data.Title
is the title that appears on top of the file dialog window.

data.InitialDirectory
sets the default start point when looking for an image file.

data.Filter
this will show only files with the .jpg extension.

data.FilterIndex
this will give only one option when choosing file types

data.RestoreDirectory
this always restores the directory to my pictures


Step two: retrieving the data

In this step we are going to create a new method calledpublic void meta()


in this method we need to add the following objects:
Bitmap image = new Bitmap(data.FileName);

PropertyItem[] propItems = image.PropertyItems;

as you can see the Bitmap object encapsulates the image which was loaded up in step one.

data.Filename
now becomes the object ref image

We use the PropertItem array to store all property items from the image as mentioned in the intro to this tutorial. this will store our meta information.

Next we need to drag a listbox onto our windows form and in form1.cs add in a counter and a
foreach loop to retrieve all information.

the listbox will be populated with the metadata.

int count = 0;
foreach (PropertyItem item in propItems)
{
listBox1.Items.Add("Property Item " + count.ToString());
listBox1.Items.Add("iD: 0x" + item.Id.ToString("x"));
count++;
}



the int count will +1 every time is goes through the foreach loop giving us the number of attributes in the metadata.
the item.Id property should return a whole list of hex numbers.

In this tutorial we are only interested in the following three:
  1. 0x010F - this hex ID will give us the camera manufacturer
  2. 0x0110 - and this will give us the model of the camera
  3. 0x9003 - this will give us the data and time the picture was taken



Next we need to add the following code outside the foreach loop:

ASCIIEncoding encodings = new ASCIIEncoding();
try
{
string make = encodings.GetString(propItems[1].Value);
listBox3.Items.Add("The equipment make is " + make + ".");
}
catch
{
listBox3.Items.Add("no Meta Data Found");
}



Here we are using the ASCIIEncoding object to translate the array of Values mentioned earlier in the tutorial. this will give us, in plain English, the data we need.

propItems[1].Value - this gives us the Value of second item in the propItems array. which will be '0x010F' this is the manufacturer name.

We could then add the following:

try
{
string model = encodings.GetString(propItems[2].Value);
listBox3.Items.Add("The model is " + model + ".");
}
catch
{
listBox3.Items.Add("no Model Found");
}
try
{
string DT = encodings.GetString(propItems[15].Value);
listBox3.Items.Add("The Date & Time is " + DT + ".");
}
catch
{
listBox3.Items.Add("no date Found");
}



this would give us the model of the camera and the date and time that the picture was taken.

The only thing left to do now is drag a new button on the windows form and call it 'Meta Data' double click it to create 'MetaData_Click' in form1.cs and add call the meta method meta();
. and what you should see when the program is run is something similar to this: