Scott Hanselman

Accessing EXIF Photo Data from JPEGs with PowerShell

September 8, '06 Comments [4] Posted in PowerShell
Sponsored By

Omar and I were chatting today and he wanted to to know how to access EXIF data from PowerShell. Omar wrote a nice little photo library a while back that extracts and interprets EXIF data from images. The .NET Framework 2.0 has some support for EXIF, but it doesn't attempt to interpret it.

Anyway, Omar wants to do some manipulation of his files, doing renaming and such, based on the EXIF data. He wanted to sort a directory by the date the format was actually TAKEN - this is stored inside the photo itself if the time is right on your camera - not the File System Dates.

We could write scripts to manipulate the files his library directly, but wouldn't it be very integrated with the whole PowerShell experience, now would it?

So, here's what we did:

  • Put Omar's PhotoLibrary.dll in your MyDocuments/PSConfiguration folder.
  • Add this to your Microsoft.PowerShell_profile.ps1 file (or make one if you don't have it):
    • $profileTypes = $profile | split-path | join-path -childPath "My.Types.ps1xml"
      Update-TypeData $profileTypes
      $photoLibrary = $profile | split-path | join-path -childPath "PhotoLibrary.dll"
      [System.Reflection.Assembly]::LoadFrom($photoLibrary)
  • Make (or add to) a My.Types.ps1xml file in your MyDocuments/PSConfiguration folder:
    • <Types>
           <Type>
              <Name>System.IO.FileInfo</Name>
              <Members>
                 <ScriptProperty>
                      <Name>DatePhotoTaken</Name>
                      <GetScriptBlock>
                      if ($this.Extension -match "jpg|raw")
                       {
                        $photo = new-object PhotoLibrary.Photo $this.FullName
                        $photo.DateTimeOriginal
                      }
                      </GetScriptBlock>
                  </ScriptProperty>
                </Members>
           </Type>
      </Types>

This is one of the most powerful aspect of PowerShell. Actually "spot-welding" new properties on to existing objects. Not object inheritance, mind you, "super-gluing." Like it or hate it, like super-glue, you have to respect that it solves problems.

Now we can do this from our PowerShell:

PS C:\Documents and Settings\shanselm\Desktop>
dir *.jpg | sort -desc DatePhotoTaken | select Name, LastWriteTime, DatePhotoTaken

Name                       LastWriteTime              DatePhotoTaken
----                       -------------              --------------
Z Q. at house Jan 1... 1/19/2006 4:26:00 PM       1/18/2006 8:01:00 AM
dadandscott.jpg            9/7/2006 2:37:32 PM        2/3/2002 2:57:03 PM

Since we're using Omar's library, we can do whatever we like with any the other EXIF details he expose:

PS C:\Documents and Settings\shanselm\Desktop>
$photo = new-object PhotoLibrary.Photo ((get-item dadandscott.jpg).Fullname)

PS C:\Documents and Settings\shanselm\Desktop>
$photo | select make, model, Width, Height, DateTimeOriginal | format-list

Make             : Eastman Kodak Company
Model            : KODAK DC265 ZOOM DIGITAL CAMERA (V01.00)
Width            : 1536
Height           : 1024
DateTimeOriginal : 2/3/2002 2:57:03 PM

Shiny.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Friday, September 08, 2006 1:21:39 AM UTC
Oh, sure... you can use PowerShell if you wish. My wife keeps telling me I need to get more excercise so I think I'll stick to using my mouse to open each file, view the properties, and then copy the file to appropriate folder. I bet I will burn at least 1 or 2 extra calories per picture, which over time will add up. That is the problem with your generation, always looking for the shortcut. ;)
Friday, September 08, 2006 6:44:06 AM UTC
Dugg, although I created a console app two weeks ago that does the file renaming to date picture taken (yyyyMMdd-HHmmss.jpg) instead of DSCxxxx.jpg. This makes it easy to sort and to see when it was taken.

Scott, is it possible to add a shortcut to the context menu that links to a PowerShell script and uses the folder path as a parameter?
Friday, September 08, 2006 1:56:44 PM UTC
It is not clear what he wants to do with the sorted data, but if he just wants to view it sorted, I dont think you need PowerShell or any code at all. You can open Explorer to the directory, right-click on the column headers, scroll down to "More...", select the checkbox next to "Date Picture Taken", and closed the dialogs. Then click on the Date Picture Taken column in Explorer to sort.
Friday, September 08, 2006 3:34:30 PM UTC
Joshua, my webserver doesn't know a column named DatePicture Taken when I request a list of jpg files through the DirectoryInfo object. Besides of that, it requires extra clicks and somehow Windows forgets that I've added the column (or I don't get the functionality).
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.