Getting EXIF data from DT records

Occasionally, people here ask how they can get EXIF data from their images into DT (custom) metadata. This is possible without installing any third-party tools using a JavaScript function like the following:

ObjC.import('AppKit');
/* Get the value for EXIF 'key' from image in 'file' */
function getEXIFvalue(file, key) {
  const img = $.NSImage.alloc.initWithContentsOfFile($(file));
  const rep = img.representations.objectAtIndex(0);
  const exifDict = rep.valueForProperty($.NSImageEXIFData);
  const exifJS = exifDict.js; /* Convert NSDictionary to JavaScript array */
  return exifJS[key].js; /* Return the value for the key as a JavaScript type */
}

You can call this function for example like this to set the creation date of images to the date/time they were taken:

  const app = Application("DEVONthink 3")
  const recs = app.selectedRecords();
  recs.forEach(r => {
    const p = r.path();
   /* Get the date and time when the picture was taken */
    const dateString =  getEXIFvalue(p, 'DateTimeOriginal');
    /* Convert the EXIF date format to ISO */
    const ISODate = dateString.replace(/(\d{4}):(\d\d):(\d\d) /,"$1-$2-$3T");
   /* Set the record's creation date to the date/time when the photo was taken */
    r.creationDate = new Date(ISODate);

Beware: There is absolutely no error checking in these examples. So if you run the code on a PDF or on a JPG not containing the EXIF key/value ‘DateTimeOriginal’, it will fail miserably.

2 Likes

It’s also possible to retrieve certain EXIF values via Image Events:

tell application id "DNtp"
	try
		repeat with this_item in selected records
			if the type of this_item is equal to picture then
				try
					set this_image to the image of this_item
					tell application "Image Events"
						set this_file to open file this_image
						set this_date to value of metadata tag "creation" of this_file
						close this_file
						-- this_date is a string and needs to be converted
					end tell
				end try
			end if
		end repeat
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

Yes :slightly_smiling_face: :

Too many scripts over here obviously :joy:

1 Like