I’m now able to read some of the tags of a photo using Image Events, but I’m not able to get the Headline tag. Does anyone know if this is possible? I tried finding if this information was available using the SD debugger info but couldn’t find the info. Am I missing something or isn’t it simple possible?
I’m using this slightly modified version of a script I found online
set this_file to (choose file without invisibles) as text
try
tell application "Image Events"
-- start the Image Events application
launch
-- open the image file
set this_image to open file this_file
-- extract the metadata values
tell this_image
set picname to the name
repeat with i from 1 to the count of metadata tags
try
set this_tag to metadata tag i
set the tag_name to the name of this_tag
set the tag_value to the value of this_tag
if i is 1 then
set the tag_text to tag_name & ": " & tag_value
else
set the tag_text to the tag_text & return & tag_name & ": " & tag_value
end if
on error
if the tag_name is "profile" then
set the tag_text to the tag_text & return & tag_name & ": " & name of tag_value
end if
end try
end repeat
set x to the count of metadata tags
end tell
-- purge the open image data
close this_image
end tell
display dialog x
display dialog picname
display dialog tag_text
on error error_message
display dialog error_message buttons {"Cancel"} default button 1
end try
In my testing, ExifTool returns IPTC tags but not Image Events or ASObjC. As you probably know, ExifTool is a free command-line utility that can be run in an AppleScript with the do shell script command. The following illustrate:
set sourceFile to quoted form of POSIX path of (choose file)
-- returns all metadata
set theData to (do shell script "/usr/local/bin/exiftool -sort " & sourceFile)
-- returns all IPTC metadata
set theData to (do shell script "/usr/local/bin/exiftool -sort -iptc:all " & sourceFile)
-- returns all XMP metadata
set theData to (do shell script "/usr/local/bin/exiftool -sort -xmp:all " & sourceFile)
-- returns headline tag
set theData to (do shell script "/usr/local/bin/exiftool -headline " & sourceFile)
You can retrieve it using ASObjC in macOS 12, but not earlier versions.
use AppleScript version "2.8" -- requires macOS 12 or later
use scripting additions
use framework "Foundation"
use framework "AppKit" -- for image stuff
set POSIXPath to POSIX path of (choose file)
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:POSIXPath
set theIPTCData to theImageRep's valueForProperty:(current application's NSImageIPTCData)
if theIPTCData is missing value then error "NoIPTC data data found"
return theIPTCData as record
I’m running macOS 12, but in my ASOjbC test script I used NSImageEXIFData rather than NSImageIPTCData, which I didn’t know existed. Works great with that change.
Thanks to both of you, I’m getting closer to what I want … sorry about being dense but AppleScript haven’t been a language that I’ve used seriously for many years. I got two additional questions.
I got everything to work except that I’ve got problems in translating the strings for date/time into a date object. The conversion works but I get the wrong date. Example
-- Trying 'date "2022-02-03"'
date "Thursday, 14 August 2008 at 00:00:00"
At first I thought it was that I had the wrong date format set, I’m running my Mac with the language set to English (US) but with the date format set to YYYY-MM-DD (I confirmed this in the settings). Any idea why I get the wrong date.
Second question: I’m pretty sure that this could be done in a better way, how would you more experienced people write this (I want a record with date, title and caption that I then can pass to other handlers).
on getphotodata(photopath)
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:photopath
set theIPTCData to theImageRep's valueForProperty:(current application's NSImageIPTCData)
if theIPTCData is missing value then error "NoIPTC data data found"
set pHeadline to (Headline of theIPTCData) as text
set pCaption to (|Caption/Abstract| of theIPTCData) as text
set pdate to (DateCreated of theIPTCData) as text
set ptime to (TimeCreated of theIPTCData) as text
set pd to (date ((text 1 thru 4 of pdate) & "-" & (text 5 thru 6 of pdate) & "-" & (text 7 thru 8 of pdate))) --+ ((text 1 thru 2 of ptime) as integer) * hours + ((text 3 thru 4 of ptime) as integer) * minutes + ((text 5 thru 6 of ptime) as integer)
return {title:pHeadline, caption:pCaption, timestamp:pd}
end getphotodata
The date comes out wrong here as described in the first question but I assume I could do this in better way?
Jan. The AppleScript Language Guide states as follows:
You can create a date object using a string that follows the date format specified in the Formats pane in International preferences.
The trouble is that there are four date formats, and, in the circumstance you cite, one would expect the short date format to be followed but it isn’t. For example, I have the short date format set to “2022/06/01”, yet I get the following results:
set theDate to "2022/02/03" -- February 3, 2022
set theDateObject to date theDate --> date "Sunday, June 2, 12171 at 12:00:00 AM"
You can correct the above by changing the other date formats, which seems undesirable, or (apparently) by using the default short date format for your locale:
set theDate to "02/03/22" -- February 3, 2022
set theDateObject to date theDate --> date "Thursday, February 3, 2022 at 12:00:00 AM"
As regards the rest of your script, theIPTCData is a dictionary and I would probably use the valueForKey method to get the value of the desired keys. One advantage of this is that “missing value” is returned if a key is not found. Also, some error correction is necessary. There are a lot of ways to write your script but my suggestion FWIW:
use AppleScript version "2.8" -- requires macOS 12 or later
use framework "AppKit"
use framework "Foundation"
use scripting additions
set photopath to POSIX path of (choose file)
set theData to getphotodata(photopath)
on getphotodata(photopath)
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:photopath
set theIPTCData to theImageRep's valueForProperty:(current application's NSImageIPTCData)
if theIPTCData is missing value then error "NoIPTC data data found"
set pHeadline to (theIPTCData's valueForKey:"Headline") as text
if pHeadline = "missing value" then set pHeadline to "No IPTC headline"
set pCaption to (theIPTCData's valueForKey:"Caption/Abstract") as text
if pCaption = "missing value" then set pCaption to "No IPTC caption"
set pDate to (theIPTCData's valueForKey:"DateCreated") as text
if pDate = "missing value" then
set pd to "No IPTC date"
else
set pd to (date ((text 5 thru 6 of pDate) & "/" & (text 7 thru 8 of pDate) & "/" & (text 3 thru 4 of pDate))) -- change for your locale
end if
return {title:pHeadline, caption:pCaption, timestamp:pd}
end getphotodata
I’d use ASObjC to do the date conversion, because I suspect the dates strings are UTC, not local time. I see the spec says TimeCreated can be 11 characters, so I presume in that case it includes a time zone value. So try something like this:
on dateFromPate:pdate andPime:ptime
set fullDate to pdate & ptime
set theFormatter to current application's NSDateFormatter's new()
theFormatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX")
theFormatter's setTimeZone:(current application's NSTimeZone's timeZoneWithAbbreviation:"GMT")
if length of fullDate = 14 then
theFormatter's setDateFormat:"yyyyMMddHHmmss"
else -- time zone included?
theFormatter's setDateFormat:"yyyyMMddHHmmssZZZ"
end if
return theFormatter's dateFromString:fullDate
end dateFromPate:andPime:
Is there a way to get the XMP data (similar to @peavine 's exiftool call)? I see there is no NSImageXMPData. We use Exiftool regularly but this use of ASObjC intrigues me if it can get at the custom XMP metadata fields that we use.
Secondarily (and more importantly for us), if it is possible to get the XMP data with ASObjC can it then also be modified on the file? This is what we’re primarily using ExifTool for. Applying custom metadata fields/values on files before we transfer to our retouch team/processing system. Would love to be able to do it without the requirement of Exiftool (just one less thing to remember to install).