Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Identify all known faces in an iPhoto photo Apps
The following AppleScript will display a dialog box showing the names of every identified face in a selected photo in iPhoto:
tell application "iPhoto"
  activate
  
  set the selected_items to (get the selection)
  repeat with z from 1 to the count of the selected_items
    set this_photo to item z of the selected_items
    select this_photo
    set the query_results to my extract_face_record(this_photo)
    if the the query_results is not false then
      set AppleScript's text item delimiters to return
      
      repeat with i from 1 to the count of the query_results
        set the info_list to item i of the query_results
        if i is 1 then
          set the dialog_text to the info_list as text
        else
          set the dialog_text to the dialog_text & return & return & the info_list as text
        end if
      end repeat
      set AppleScript's text item delimiters to ""
      display dialog dialog_text
    end if
  end repeat
  select selected_items
end tell

on extract_face_record(this_photo)
  -- locate the current iPhoto library
  set iPhoto_library_path to do shell script "defaults read com.apple.iPhoto RootDirectory"
  -- expand the '~' if it's in there
  set iPhoto_library_path to do shell script "echo " & iPhoto_library_path
  -- add trailing slash if necessary
  if iPhoto_library_path does not end with "/" then
    set iPhoto_library_path to iPhoto_library_path & "/"
  end if
  
  -- locate the databases
  set the database_path to iPhoto_library_path & "face.db"
  set the iPhoto_database_path to iPhoto_library_path & "iPhotoMain.db"
  
  -- get the file path of the photo file
  tell application "iPhoto"
    if the class of this_photo is not photo then return false
    set the file_POSIX_path to the image path of this_photo
  end tell
  
  if the file_POSIX_path starts with iPhoto_library_path then
    set l to length of iPhoto_library_path
    set the file_POSIX_path to (text (l + 1) through -1 of the file_POSIX_path)
  end if
  
  -- get the file info record for the image file
  set the file_info_key to my SQL_command(iPhoto_database_path, "select primaryKey from SQFileInfo where relativePath=\"" & file_POSIX_path & "\";")
  if (count of paragraphs of the file_info_key) is greater than 1 then set the file_info_key to first paragraph of the file_info_key
  
  --get photo Key/ image key for the file info record
  set imageKey to my SQL_command(iPhoto_database_path, "select photoKey from SQFileImage where sqFileInfo=\"" & the file_info_key & "\";")
  
  --get detected faces for the image key
  set the face_keys to every paragraph of (my SQL_command(database_path, "select face_key from detected_face where image_key=\"" & imageKey & "\";"))
  
  -- create a list for each face {short name, full name, email address}
  set the face_records to {}
  repeat with this_key in the face_keys
    set this_face_info to {}
    -- get name
    set the short_name to my SQL_command(database_path, "select name from face_name where face_key=\"" & this_key & "\";")
    set the end of this_face_info to the short_name
    -- get full name
    set the full_name to my SQL_command(database_path, "select full_name from face_name where face_key=\"" & this_key & "\";")
    set the end of this_face_info to the full_name
    -- get email address
    set this_email to my SQL_command(database_path, "select email from face_name where face_key=\"" & this_key & "\";")
    set the end of this_face_info to this_email
    
    set the end of face_records to this_face_info
  end repeat
  
  return face_records
end extract_face_record

on SQL_command(database_path, command_string)
  return (do shell script "sqlite3 " & (quoted form of database_path) & " '" & command_string & "'")
end SQL_command
To use this, save it as a script in your user's Library » Scripts » Applications » iPhoto folder; create any of those folders as necessary when saving. You can then run it directly from the Scripts menu within iPhoto, after first selecting a photo to work with.

[robg adds: For AppleScripters working with iPhoto, the above may be useful as an example of how to find face information for selected photos. I tested it, and it works as described to extract a list of faces for a selected photo.]
    •    
  • Currently 2.88 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (17 votes cast)
 
[8,982 views]  

Identify all known faces in an iPhoto photo | 9 comments | Create New Account
Click here to return to the 'Identify all known faces in an iPhoto photo' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Identify all known faces in an iPhoto photo
Authored by: Dave Creek on Feb 19, '10 01:06:45PM

Would this work in Aperture, too, assuming that "iPhoto" is changed to "Aperture" throughout the script?



[ Reply to This | # ]
Aperture
Authored by: mr. applescript on Feb 22, '10 12:16:04AM

I haven't looked into the structure of the Aperture faces database yet, so I don't know if this same method will work. If it does, or there is a way to do the same thing, I'll post the script.



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: Brak on Feb 20, '10 07:56:05AM

OMG THANK YOU! Finally I won't get duplicates that even proliferate across to my cellphone too. god. finally some peace.



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: Helge33 on Feb 22, '10 01:37:57AM

Interesting insight in iPhoto. So the Program does not store Faces as keywords attached to each file but rather in a deeply buried SQL database?
So expect a nightmare if you want to transfer or export your picture library...



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: ssj152 on Feb 24, '10 09:54:30AM

OK, I'm dumb. I created the script, tested it in the applescript editor, compiled it, created the "macintosh hd/users/myname/library/scripts/applications/iphoto" directory and put the script "show-names" there.

I restarted iPhoto but --- where are the scripts shown in iPhoto?

I am a VERY long time computer user ('71) but an absolute newbie to applescript.

Someone - please help



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: ebow on Mar 13, '10 10:03:34AM

I struggled with this. For my setup (OS X 10.5, iPhoto '09) I figured out that I had to enable the system-wide Script menu: In the AppleScript Utility, make sure "Show Script menu in menu bar" is checked. The "identify all faces" script should then show up when you're in iPhoto. This might be obvious to some, but it wasn't to me. Hope this helps!



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: ssj152 on Mar 13, '10 01:35:09PM

Thanks! You are right - that certainly isn't obvious, especially to a newbie to using / writing scripts.



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: troyb_2006 on Nov 27, '11 09:27:26AM

Hi,

I've saved the script and in Applescript Editor it is working perfectly. My only question is where are the results being saved? or is there away to have the information exported to an email?

I'm sorry if this sounds stupid but I'm new to Applescripting.



[ Reply to This | # ]
Identify all known faces in an iPhoto photo
Authored by: tdoyle on Feb 05, '12 07:46:36AM

I've converted this script to access Aperture (version 3.2.2) databases. I also added a routine to grab all of the face names in the database. I believe this script to be safe, but be sure to back up your data before using.


-- Get Aperture Face Names
-- 2012, Tim Doyle
-- Based on mr. applescript's iPhoto script, posted at http://hints.macworld.com/article.php?story=20090302060210294

tell application "Aperture"
activate

set the selected_items to the selection
repeat with z from 1 to the number of items in selected_items
set this_photo to item z of selected_items
set the query_results to my extract_face_record(this_photo)
if the the query_results is not false then
set AppleScript's text item delimiters to return

repeat with i from 1 to the count of the query_results
set the info_list to item i of the query_results
if i is 1 then
set the dialog_text to the info_list as rich text
else
set the dialog_text to the dialog_text & return & the info_list as rich text
end if
end repeat
set AppleScript's text item delimiters to ""
display dialog dialog_text
end if
end repeat
--select selected_items
end tell

-- Get and display the names of all Faces in the current Library
set the face_names to my get_all_faces()
repeat with z from 1 to the number of items in face_names
set this_face to item z of face_names
if z is 1 then
set the dialog_text to this_face
else
set the dialog_text to the dialog_text & return & this_face
end if
end repeat
tell application "Aperture"
display dialog dialog_text
end tell



on extract_face_record(this_photo)
set Aperture_library_path to do shell script "defaults read com.apple.Aperture LibraryPath"
-- expand the '~' if it's in there
set Aperture_library_path to do shell script "echo " & Aperture_library_path
if Aperture_library_path does not end with "/" then
set Aperture_library_path to Aperture_library_path & "/"
end if

set the Faces_database_path to Aperture_library_path & "Database/apdb/faces.db"
set the Aperture_database_path to Aperture_library_path & "Database/apdb/Library.apdb"

-- Get the UUID for this photo version
set the photoID to the id of this_photo

-- Look up the UUID for the master of this version
set the masterID to my SQL_command(Aperture_database_path, "select masterUuid from RKVersion where uuid=\"" & photoID & "\";")

-- Look up the face keys for all faces in this master photo, list them from left to right
set the face_keys to every paragraph of (my SQL_command(Faces_database_path, "select faceKey from RKDetectedFace where masterUuid=\"" & masterID & "\" AND rejected=0 AND ignore=0 ORDER BY topLeftX;"))

-- create a list for each face {short name, full name, email address}
set the face_records to {}
repeat with this_key in the face_keys
set this_face_info to {}
-- get name
set the short_name to my SQL_command(Faces_database_path, "select name from RKFaceName where faceKey=\"" & this_key & "\";")
if short_name is "" then
set short_name to "unnamed"
end if

set the end of this_face_info to the short_name

-- Additional fields, if desired

-- get full name
-- set the full_name to my SQL_command(Faces_database_path, "select fullName from RKFaceName where faceKey=\"" & this_key & "\";")
-- set the end of this_face_info to the full_name

-- get email address
-- set this_email to my SQL_command(Faces_database_path, "select email from RKFaceName where faceKey=\"" & this_key & "\";")
-- set the end of this_face_info to this_email

set the end of face_records to this_face_info
end repeat

return face_records
end extract_face_record


on get_all_faces()
-- Get the names of all faces in this database
set Aperture_library_path to do shell script "defaults read com.apple.Aperture LibraryPath"
-- expand the '~' if it's in there
set Aperture_library_path to do shell script "echo " & Aperture_library_path
if Aperture_library_path does not end with "/" then
set Aperture_library_path to Aperture_library_path & "/"
end if
set the Faces_database_path to Aperture_library_path & "Database/apdb/faces.db"
set the face_names to every paragraph of (my SQL_command(Faces_database_path, "select name from RKFaceName ORDER BY name;"))
end get_all_faces


on SQL_command(database_path, command_string)
return (do shell script "sqlite3 " & (quoted form of database_path) & " '" & command_string & "'")
end SQL_command



[ Reply to This | # ]