Page 1 of 1

How to Read Image Metadata in C#

#1 Zdrenka  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 116
  • Joined: 24-November 09

Posted 08 May 2011 - 11:52 AM

Hey guys, this is my first tutorial so please be kind, although any pointers would be appreciated.

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:
  • ID - the ID property can contain information about the camera used to take the photo.
  • Value - this is an array of values, the format is decided by the type property.
  • Len - this tells us the length (in bytes) of the value property.
  • 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 called
public 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:
  • 0x010F - this hex ID will give us the camera manufacturer
  • 0x0110 - and this will give us the model of the camera
  • 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:

Posted Image

Is This A Good Question/Topic? 4
  • +

Replies To: How to Read Image Metadata in C#

#2 Sergio Tapia  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1252
  • View blog
  • Posts: 4,168
  • Joined: 27-January 10

Posted 14 May 2011 - 08:06 AM

Hey this is pretty interesting. :) +1
Was This Post Helpful? 0
  • +
  • -

#3 Zdrenka  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 116
  • Joined: 24-November 09

Posted 14 May 2011 - 04:04 PM

thanks, I thought some might find it useful :D
Was This Post Helpful? 0
  • +
  • -

#4 Happyhour  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 12-April 11

Posted 15 May 2011 - 10:37 AM

Nice tut. I was just looking up how to do this a few days ago too.
Was This Post Helpful? 0
  • +
  • -

#5 Wasim Fatair  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 17-May 11

Posted 17 May 2011 - 12:30 AM

Interesting ..
but when we talk about getting the hole metadata(For example : Caption, Keywords, Copyright Notice, Caption Writer, Also the IPTC Data) it will be totally differences
Was This Post Helpful? 0
  • +
  • -

#6 Zdrenka  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 116
  • Joined: 24-November 09

Posted 17 May 2011 - 11:34 AM

well the list box shows all the metadata in the image so it would simply be a case of finding where the comments, caption etc.. are and adding it to a string for example

string model = encodings.GetString(propItems['number of value'].Value);


in most cases though you don't really get that information in the image files but it is possible to add metadata to a file although this would have to be another tutorial, though its roughly just adding a value to the PropertyItem object as shown below:

var comment = System.Text.Encoding.UTF8.GetBytes( "Some comments" );
PropItems.Type = 2;
PropItems.Id = 37510;
PropItems.Len = comment.Length;
PropItems.Value = comment;


This post has been edited by Zdrenka: 17 May 2011 - 12:15 PM

Was This Post Helpful? 0
  • +
  • -

#7 codeprada  Icon User is offline

  • Changed Man With Different Priorities
  • member icon

Reputation: 943
  • View blog
  • Posts: 2,353
  • Joined: 15-February 11

Posted 19 May 2011 - 07:56 AM

Nice tutorial, I'll try it when I get home.

Just out of curiosity would this method with the proper hexadecimal numbers work with audio files as well?
Was This Post Helpful? 0
  • +
  • -

#8 Zdrenka  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 7
  • View blog
  • Posts: 116
  • Joined: 24-November 09

Posted 19 May 2011 - 01:49 PM

I don't think so, I haven't worked with audio files but I'm pretty sure the metadata in an MP3 is stored differently then in a JPEG. though I could be wrong
Was This Post Helpful? 0
  • +
  • -

#9 electriac  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 1
  • Joined: 17-April 13

Posted 17 April 2013 - 03:10 AM

Also

[code]

private static ASCIIEncoding ASCIIencoding = new ASCIIEncoding();

private static string readImageProperty(Image image, int ID)
{

try
{
PropertyItem pi = image.GetPropertyItem(ID);
if (pi.Type == 2) //ASCII
{
return ASCIIencoding.GetString(pi.Value, 0, pi.Len - 1);

}
if (pi.Type == 5) //rational
{
byte[] bb = pi.Value;
uint uNominator = BitConverter.ToUInt32(bb, 0);
uint uDenominator = BitConverter.ToUInt32(bb, 4);
if (uDenominator == 1) return uNominator.ToString();
return uNominator.ToString() + "/" + uDenominator.ToString();
}
}
catch
{
}
return "Not Found";
}

public void metaData(string fname)
{
Bitmap image = new Bitmap(fname);
PropertyItem[] propItems = image.PropertyItems;
textBox1.Clear();
//listBox2.Items.Clear();
//string fname = data.FileName;
textBox1.AppendText(Environment.NewLine + "File Name = " + fname);
textBox1.AppendText(Environment.NewLine + "Image Aspect = " + image.Width + "x" + image.Height);
FileInfo fi = new FileInfo(fname);
long size = fi.Length;
size = (size + 1023) / 1024;
textBox1.AppendText(Environment.NewLine + "File Size = " + size + "KB");
textBox1.AppendText(Environment.NewLine + "Date = " + readImageProperty(image, 0x132));
textBox1.AppendText(Environment.NewLine + "The equipment make = " + readImageProperty(image, 0x110));
textBox1.AppendText(Environment.NewLine + "Exposure Time = " + readImageProperty(image, 0x829A));
textBox1.AppendText(Environment.NewLine + "Focal Length = " + readImageProperty(image, 0x920A));
}

[/code
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1