Getting EXIF metadata from image files

This is a newbie attempt at discovering the creation date of photos. Please note that it is the photo creation date that I want, not the file creation date, so I am looking at the EXIF metadata in the image files.

This test script works:


set theFile to choose file
tell application "Image Events"
	set theOpenedFile to open theFile
	tell theOpenedFile
		set theTag to metadata tag "creation"
		set theTagValue to value of theTag
	end tell
	close theOpenedFile
end tell
display dialog theTagValue

But when I try to iterate the files in the folder, it doesn’t work. See error message on the “set theTag to metadata tag” statement below.


tell application "Finder"
	set theFileList to every file of folder POSIX file "/Users/Alan/Desktop/Test"
end tell
repeat with theFile in theFileList
	tell application "Image Events"
		set theOpenFile to open theFile
		tell theOpenedFile
			set theTag to metadata tag "creation" -- Image Events error message: Can't get image "P1000002.jpg"
			set theTagValue to value of theTag
		end tell
		close theOpenedFile
	end tell
	display dialog theTagValue
end repeat

Help!

Model: iMac
AppleScript: 2.5
Browser: Safari 601.2.7
Operating System: Mac OS X (10.10)

Try changing the second line to:

   set theFileList to every file of folder POSIX file "/Users/Alan/Desktop/Test" as alias list

The problem is that you are passing Finder file references, which only Finder understands, to Image Events.

Thanks for that. I seem to be making progress. The revised version is below. It now fails at the same place on the second iteration with the same error message.


tell application "Finder"
	set theFileList to every file of folder POSIX file "/Users/Alan/Desktop/Test" as alias list
end tell
repeat with theFile in theFileList
	tell application "Image Events"
		set theOpenFile to open theFile
		tell theOpenedFile
			set theTag to metadata tag "creation" -- Image Events error message: Can't get image "P1000002.jpg"
		end tell
		set theTagValue to value of theTag
		close theOpenedFile
	end tell
	display dialog theTagValue
end repeat

I am obviously making some elementary mistake. Any ideas?

Model: iMac
AppleScript: 2.5
Browser: Safari 601.2.7
Operating System: Mac OS X (10.10)

You use theOpenFile and theOpenedFile. However, that gives a different error message, which suggests the code you are running is not the code you are posting.

You are quite right: there was some preceding code in my test script, which I removed to simplify things. I have got rid of that and corrected the error you pointed out. Result: it works!

For the record:


tell application "Finder"
	set theFileList to every file of folder POSIX file "/Users/Alan/Desktop/Test" as alias list
end tell
repeat with theFile in theFileList
	tell application "Image Events"
		set theOpenFile to open theFile
		tell theOpenFile
			set theTag to metadata tag "creation"
		end tell
		set theTagValue to value of theTag
		close theOpenFile
	end tell
	set fileName to POSIX path of theFile
	display dialog fileName & return & theTagValue
end repeat

A supplementary question:

Can anybody direct me to a definitive guide to EXIF image-file metadata?

I have a problem: the following script gives the wrong creation date “ it returns the last-modified date of the file, not the photo creation date. (Zoner Photo Studio 17 gives the right date for the exact same file.)


set theFile to choose file -- get image file
tell application "Image Events" -- a hidden built-in application
	activate
	set theOpenedFile to open theFile
	tell theOpenedFile
		set theTagList to ""
		repeat with i from 1 to the count of metadata tags -- iterate EXIF data
			set theTag to metadata tag i
			set the theTagName to the name of theTag
			set the theTagValue to the value of theTag
			if theTagList is not "" then set theTagList to theTagList & return
			try
				set theTagList to theTagList & theTagName & ": " & theTagValue
			on error
				if theTagName is "profile" then
					set theTagList to theTagList & theTagName & ": " & name of theTagValue
				else
					set theTagList to theTagList & theTagName & ": " & "?"
				end if
			end try
		end repeat
	end tell
	close theOpenedFile
end tell
display dialog theTagList -- must be outside Image Events, presumably to avoid hogging access to file

Help please!

Model: iMac
AppleScript: 2.5
Browser: Safari 601.2.7
Operating System: Mac OS X (10.10)

This looks fairly comprehensive:

www.exiv2.org/tags.html

But the metadata tags returned by Image Events are only partly based in EXIF tags, and not all EXIF tags are required.

Run this script and select one of your files. Compare the date you are getting with Image Events to the DateTimeOriginal and DateTimeDigitized values returned by this script, and tell us if they match.

use scripting additions
use framework "Foundation"
use framework "AppKit" -- for image stuff

set POSIXPath to POSIX path of (choose file)
my readEXIFFromJpeg:POSIXPath
on readEXIFFromJpeg:POSIXPath
	set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:POSIXPath
	set theEXIFData to theImageRep's valueForProperty:(current application's NSImageEXIFData)
	return theEXIFData as record
end readEXIFFromJpeg:

Thanks for that.

Result of running your script: DateTimeOriginal and DateTimeDigitized are correct “ they both record the moment the camera shutter clicked.

The obvious next question is “How do I access those values in AppleScript?”

set timeString to DateTimeOriginal of my readEXIFFromJpeg:POSIXPath

Thanks for that (belatedly). I’ve woken up again!

When I run this:


use scripting additions
use framework "Foundation"
use framework "AppKit" -- for image stuff
set POSIXPath to POSIX path of (choose file)
set timeString to DateTimeOriginal of (my readEXIFFromJpeg:POSIXPath)

I get an obscure error message:

*** -[BAGenericObjectNoDeleteOSAID readEXIFFromJpeg:]: unrecognized selector sent to object <BAGenericObjectNoDeleteOSAID @0x7fbc7cfcd840: OSAID(1) ComponentInstance(0x880002)>

I think it’s not recognising “readEXIFFromJpeg”.

Help!

Model: iMac
AppleScript: 2.5
Browser: Safari 601.2.7
Operating System: Mac OS X (10.10)

You would get better results with :


use scripting additions
use framework "Foundation"
use framework "AppKit" -- for image stuff
set POSIXPath to POSIX path of (choose file)
set theGrabbedExifs to my readEXIFFromJpeg:POSIXPath
(*DateTimeOriginal:2014:02:18 12:29:56, MeteringMode:5, SensingMethod:2, MaxApertureValue:4.2, DigitalZoomRatio:1.0, FocalLenIn35mmFilm:66, FNumber:9.0, FocalLength:44.0, SceneCaptureType:0, SceneType:1, FileSource:3, Saturation:0, Sharpness:0, GainControl:1, CFAPattern:1, 2, 0, 1, SubjectDistRange:0, Contrast:0, WhiteBalance:0, UserComment:                                    , LightSource:0, DateTimeDigitized:2014:02:18 12:29:56, ISOSpeedRatings:400, ExposureMode:0, CustomRendered:0, ExposureProgram:0, Flash:0, SubsecTimeDigitized:30, SubsecTimeOriginal:30, ExposureTime:0.003125, SubsecTime:30, ExposureBiasValue:0.0*)
if theGrabbedExifs is {} then
	display dialog "No exifs available !"
else
	try
		set timeString to DateTimeOriginal of theGrabbedExifs
	on error
		display dialog "There is no DateTimeOriginal info in the exifs available !"
	end try
end if

on readEXIFFromJpeg:POSIXPath
	set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:POSIXPath
	set theEXIFData to theImageRep's valueForProperty:(current application's NSImageEXIFData)
	try
		set theExifs to theEXIFData as record
	on error
		# Here if theExifDatas is missing value.
		set theExifs to {}
	end try
	return
end readEXIFFromJpeg:

I have pictures with no exifs at all. I have some with no DateTimeOriginal info so the script must be aware of that.
When there is no exif, the instruction:
return theEXIFData as record
fails with the comprehensive message : can’t coerce missing value as record
When we have exifs without DateTimeOriginal, your original code would fail with the comprehensive message : no DateTimeOriginal !

A script has only the intelligence which we give it. If we give none, it can’t achieve the wanted task.

Yvan KOENIG running El Capitan 10.11.1 in French (VALLAURIS, France) lundi 7 décembre 2015 16:19:18

Yvan,

Many thanks for that. With one or two adjustments, it worked!

Regards,
AlanWM

Shane,

Thanks for a great script.

I’m still learning JXA and could use a good example here.
When you have a chance, could you please convert this to a JXA script?

Many thanks!

Not really. Last I looked at JXA, it wasn’t worth the effort.

Great script thank you!
I was trying to make this script working with an already selected file in the finder, I did convert the selection to Alias but it doesn’t seem to work, do you have any idea how to do that?

thanks

Shane’s script is indeed very useful. I edited it for my use with a Finder selection and have posted the base script here FWIW. I have to add a dialog or similar for output and a bit more error correction.

use scripting additions
use framework "Foundation"
use framework "AppKit" -- for image stuff

tell application "Finder" to set theFile to selection as alias list
if (count theFile) is not equal to 1 then display dialog "Multiple or no files selected" buttons {"OK"} cancel button 1 default button 1 with icon stop

set POSIXPath to POSIX path of theFile
set theEXIFData to my readEXIFFromJpeg:POSIXPath

on readEXIFFromJpeg:POSIXPath
	set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:POSIXPath
	set theEXIFData to theImageRep's valueForProperty:(current application's NSImageEXIFData)
	return theEXIFData as record
end readEXIFFromJpeg:

Hi,

Image Events and AsObjC can retrieve only part of exif-data of “public.image” files. See the real power with exiftool (free):


property exiftoolPath : "/usr/local/bin/exiftool"

-- set imagePath to quoted form of (POSIX path of (choose file of type "public.image"))

tell application "Finder" to set theAlias to (item 1 of (get selection)) as alias
set imagePath to quoted form of (POSIX path of theAlias)

-- Get all metadata
do shell script exiftoolPath & " -a -u -g1 " & imagePath