Reading and displaying EXIF photo data on Windows Phone

Here I am again. I haven’t written anything smart for a while now because I’ve been working on my next Windows Phone application called Photo Light. It should be out in less than 10 days, and it will be a small, light and free photo editor. One of the things it does is display EXIF data of the loaded photo. In this article, I’ll describe how to read the EXIF data for a photo and display it in a page. Let’s get started.

First of all, to get the EXIF of a photo, we need to get a photo. To do that, we use a PhotoChooserTask object which returns us the chosen photo. Then we need a way to read the EXIF data from the returned stream. What’s the problem here? Well, the problem is how to get that data. There is a cute little library that does the job. It’s called ExifLib and it’s available on Code Project under Code Project Open License. But don’t go downloading it yet! The version that’s on Code Project won’t do the job, because we’re not working strictly with files and file names, which the library requests, but with the stream of data given back from the PhotoChooserTask. In order to get it to work with Windows Phone, go to the blog post of Tim Heuer who did a slight modification of the library to work with WP7. Download his project and get the library from Libs folder! Add it to your newly created Windows Phone project.  When the application launches, launch the PhotoChooserTask. It will return you the chosen photo, which you can then use to create JpegInfo object and get all the info for the selected JPEG. Here’s how it looks in the end:

exif

You’ll notice that a lot of information is missing, but it will work better once you try it on the phone with a photo you’ve taken with the camera!

Here’s the layout XAML from MainPage.xaml:

<Grid x:Name="LayoutRoot" Background="Transparent">  
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="EXIF READER" Style="{StaticResource PhoneTextNormalStyle}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Margin="12,0,12,0" Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="2*"/>
            </Grid.RowDefinitions>
                <Image Name="loadedImg" MaxHeight="300" HorizontalAlignment="Center" Grid.Row="0"/>
            <ScrollViewer Margin="12" Grid.Row="1">
                <StackPanel Margin="12">
                <TextBlock Name="artist" Margin="12,0"/>
                <TextBlock Name="copyright" Margin="12,0"/>
                <TextBlock Name="datetime" Margin="12,0"/>
                <TextBlock Name="description" Margin="12,0"/>
                <TextBlock Name="exposure" Margin="12,0"/>
                <TextBlock Name="filename" Margin="12,0"/>
                <TextBlock Name="filesize" Margin="12,0"/>
                <TextBlock Name="flash" Margin="12,0"/>
                <TextBlock Name="fnumber" Margin="12,0"/>
                <TextBlock Name="gpslatitude" Margin="12,0"/>
                <TextBlock Name="gpslatituderef" Margin="12,0"/>
                <TextBlock Name="gpslongitude" Margin="12,0"/>
                <TextBlock Name="gpslongituderef" Margin="12,0"/>
                <TextBlock Name="height" Margin="12,0"/>
                <TextBlock Name="iscolor" Margin="12,0"/>
                <TextBlock Name="isvalid" Margin="12,0"/>
                <TextBlock Name="loadtime" Margin="12,0"/>
                <TextBlock Name="make" Margin="12,0"/>
                <TextBlock Name="orientation" Margin="12,0"/>
                <TextBlock Name="resolutionunit" Margin="12,0"/>
                <TextBlock Name="software" Margin="12,0"/>
                <TextBlock Name="thumbdata" Margin="12,0"/>
                <TextBlock Name="thumboffset" Margin="12,0"/>
                <TextBlock Name="thumbsize" Margin="12,0"/>
                <TextBlock Name="usercomment" Margin="12,0"/>
                <TextBlock Name="width" Margin="12,0"/>
                <TextBlock Name="xresolution" Margin="12,0"/>
                <TextBlock Name="yresolution" Margin="12,0"/>
                </StackPanel>
            </ScrollViewer>
        </Grid>
    </Grid>

And here’s the MainPage.xaml.cs, the code behind:

public partial class MainPage : PhoneApplicationPage  
{
    // Constructor

    bool photoLoaded = false;

    public MainPage()
    {
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        InitializeComponent();
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!photoLoaded)
        {
            PhotoChooserTask task = new PhotoChooserTask();
            task.Completed += new EventHandler<PhotoResult>(task_Completed);
            task.Show();
        }
    }

    void task_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            photoLoaded = true;
            JpegInfo info = ExifLib.ExifReader.ReadJpeg(e.ChosenPhoto, e.OriginalFileName);
            var img = new BitmapImage();
            img.SetSource(e.ChosenPhoto);
            loadedImg.Source = img;
            ReadExif(info);
        }
    }

    private void ReadExif(JpegInfo info)
    {
        artist.Text = "Artist: " + info.Artist;
        copyright.Text = "Copyright: " + info.Copyright;
        datetime.Text = "Datetime: " + info.DateTime;
        description.Text = "Description: " + info.Description;
        exposure.Text = "Exposure: " + info.ExposureTime;
        filename.Text = "File name: " + info.FileName;
        filesize.Text = "File size: " + info.FileSize;
        flash.Text = "Flash: " + info.Flash;
        fnumber.Text = "F number: " + info.FNumber;
        gpslatitude.Text = "GPS Latitude: " + info.GpsLatitude;
        gpslatituderef.Text = "GPS Latitude ref: " + info.GpsLatitudeRef;
        gpslongitude.Text = "GPS Longitude: " + info.GpsLongitude;
        gpslongituderef.Text = "GPS Longitude ref: " + info.GpsLongitudeRef;
        height.Text = "Height: " + info.Height;
        iscolor.Text = "Is color: " + info.IsColor;
        isvalid.Text = "Is valid: " + info.IsValid;
        loadtime.Text = "Load time: " + info.LoadTime;
        make.Text = "Make: " + info.Make;
        orientation.Text = "Orientation: " + info.Orientation;
        resolutionunit.Text = "Resolution unit: " + info.ResolutionUnit;
        software.Text = "Software: " + info.Software;
        thumbdata.Text = "Thumbnail data: " + info.ThumbnailData;
        thumboffset.Text = "Thumbnail offset: " + info.ThumbnailOffset;
        thumbsize.Text = "Thumbnail size: " + info.ThumbnailSize;
        usercomment.Text = "User comment: " + info.UserComment;
        width.Text = "Width: " + info.Width;
        xresolution.Text = "X resolution: " + info.XResolution;
        yresolution.Text = "Y resolution: " + info.YResolution;
        photoLoaded = true;
    }
}

So, now you know how to get the EXIF data for the pictures on your phone. I hope this was helpful. You will be able to find EXIF data reader in my Photo Light application that will be published and available in less than 10 days. I will make sure you know about it when it gets published, just follow my blog. :)

comments powered by Disqus