Extract info from list

Hi All,

I have a script that will extract EXIF info from an image.


set myFile to (choose file)
tell application "GraphicConverter"
	try
		get file exif myFile
		set ImgExif to result
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no exif data"
	end try
end tell
return ImgExif

The script returns the info below.


{"$0000,$00FE,Unknown tag (254),0", "$0000,$0100,Image width,600", "$0000,$0101,Image height,480", "$0000,$0102,Number of bits per component,{8,8,8}", "$0000,$0103,Compression scheme,reserved", "$0000,$0106,Pixel composition,RGB", "$0000,$010F,Make,Phase One", "$0000,$0110,Model,H 20", "$0000,$0111,Image data location,{19940,20330,20732,21158,21584,21982,22372,22724,23082,23690,...}", "$0000,$0115,Number of components,3", "$0000,$0116,Number of rows per strip,4", "$0000,$0117,Bytes per compressed strip,{389,402,426,426,397,390,351,357,607,725,...}", "$0000,$011A,X resolution,72.0 ppi (pixel per inch)", "$0000,$011B,Y resolution,72.0 ppi (pixel per inch)", "$0000,$011C,Image data arrangement,1", "$0000,$0128,Resolution unit,inch", "$0000,$0131,Software,Adobe Photoshop 7.0", "$0000,$0132,File date and time,2005:08:21 10:09:59", "$0000,$013D,Unknown tag (317),2", "$0000,$02BC,Unknown tag (700),", "$0000,$8649,Unknown tag (34377),", "$0000,$8769,-- Exif IFD --,", "$8769,$8827,ISO speed rating,100", "$8769,$9000,Exif version,0210", "$8769,$9003,Date and time of original data generation,2005:08:04 16:58:35", "$8769,$9004,Date and time of digital data generation,2005:08:04 16:58:35", "$8769,$9101,Meaning of each component,RGB", "$8769,$A000,Supported Flashpix version,0100", "$8769,$A001,Color Space,Uncalibrated", "$8769,$A002,Valid image width in pixel,600", "$8769,$A003,Valid image height in pixel,480", "$0000,$8773,Unknown tag (34675),"}

How can I extract each section of the EXIF info into a variable? For instance the second item in the list “$0000,$0100,Image width,600” I would like to set variable imgWidth to 600 and so on for each item in the list or maybe just a handfull of the ones I really need.

Any Thoughts?

Thanks,
MT

Hello -

Looks like what you have there is:

{

“Item1,Item2,Item3,Item4”
separated by ', ’ (no quotes)
}

You can probably do something with this with a list, but here’s another way of doing it:

  1. Strip off the first and last characters.
  2. Set AppleScript text item delimiters to ', ’ (no quotes)
  3. repeat with i from 1 to count words in ImgExif
  4. Set AppleScript text item delimiters to ‘,’ (no quotes)
  5. set TheValue to word 4 of word i of ImgExif

Now, there’s no way of creating variables with names specified in a string (like variable variables in php - a brilliant concept) so you’ll need to have one line for each variable as:

Set UnknownTag254 to TheValue
Set ImageWidth to TheValue
Set ImageHeight to TheValue
and so on.

Sorry for not doing the script for you - not quite enough time this morning!

Hamish

Hi MT,

perhaps these EXIF data are sufficient

set myFile to (choose file)
tell application "Image Events"
	open myFile
	set {formatOptions, hasAlpha, space_, pixelHeight, typeIdentifier, bitsPerSample, creation, path_, make_, profile_, dpiWidth, model, pixelWidth, samplesPerPixel, dpiHeight, format_, software} to value of metadata tags of image 1
end tell

My images seem to have a more restricted set (only 12 metadata tags), Stefan, so the OP may have to “tune” his set to whatever he has:

First, run


set myFile to (choose file)
tell application "Image Events"
	open myFile
	set T to metadata tags of image 1
end tell

to find out what they are. In my case:


set myFile to (choose file)
tell application "Image Events"
	open myFile
	set {formatOptions, hasAlpha, space_, pixelHeight, typeIdentifier, bitsPerSample, path_, dpiWidth, pixelWidth, samplesPerPixel, dpiHeight, format_} to value of metadata tags of image 1
end tell

In this cas(es) I miss the capability to define a record like this

set myFile to (choose file)
tell application "Image Events"
	open myFile
	set a to {}
	repeat with i in metadata tags of image 1
		tell i to set end of a to {name:value} -- doesn't work
	end repeat
end tell

Hi All,

Thanks for your replies.

Stefan - your script does return data in a nice list which I can extract info from but I think there may be an issue in the
“to value of metadata tags of image 1” as this always returns the same data not the data from the last file selected at the prompt. I have two different digital systems. One is a Canon and the other is a PhaseOne digital back. If I select a Canon file it returns the proper info. If I then select a PhaseOne file it still returns the Canon info. If I change “image 1” to “image 2” the data changes.

This script


set myFile to (choose file)
tell application "GraphicConverter"
	try
		get file exif myFile
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no exif data"
	end try
end tell

Always returns the the EXIF of the image that was chosen at the prompt but the list is full of info I don’t need.

Your script


set myFile to (choose file)
tell application "Image Events"
	open myFile
	set {formatOptions, hasAlpha, space_, pixelHeight, typeIdentifier, BitsPerSample, creation, path_, make_, profile_, dpiWidth, model, pixelWidth, samplesPerPixel, dpiHeight, format_} to value of metadata tags of image 1
end tell

Always returns the data of image 1 but I need it to return the EXIF of the selected or current image then format it into a more manageable list.

Then from the list I’ll create variables using something like.


tell application "Image Events"
	open myFile
	set {formatOptions, hasAlpha, space_, pixelHeight, typeIdentifier, BitsPerSample, creation, path_, make_, profile_, dpiWidth, model, pixelWidth, samplesPerPixel, dpiHeight, format_} to value of metadata tags of image 1
end tell
set myEXIF to result as list

set CameraModel to  item 12 of myEXIF

What I need this script to do in the end is read the EXIF of an image collect various EXIF info from that image then write the EXIF data to back to the same image but into IPTC fields using Graphic Converter.

My end goal is to be able to have some info like camera model, aperture, shutter speed, iso etc., which is stored in EXIF written back to the file it was read from but into custom IPTC fields so I can display it on the web. I already have software on my web server that will display IPTC info from the images I just need to get the info into the metadata of the image.

From a folder alias for each JPEG

  1. retrieve EXIF info from the image
  2. extract data from the EXIF info (camera model, aperture, shutter speed, iso etc.,)
  3. make the extracted info into list
  4. create variables from the list
  5. write the variables into custom IPTC fields for that image
  6. go to next image then repeat

This will actually be added to a larger script that will pass a folder path onto this section.

Thanks so much for all your input!

MarkT

Hi Mark,

if you need Shutter speed information than Image Events is the wrong solution.

With a modification of your origin script you get two lists:
nameList contains the names of the parameters, valueList the correspondent values

set myFile to (choose file)
tell application "GraphicConverter"
	try
		set ImgExif to (get file exif myFile)
		set {nameList, valueList} to {{}, {}}
		set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ","}
		repeat with i in ImgExif
			if text item 3 of i does not contain "Unknown" then
				set end of nameList to text item 3 of i
				set end of valueList to text item 4 of i
			end if
		end repeat
		set AppleScript's text item delimiters to ASTID
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no exif data"
	end try
end tell

Stefan,

Your script works great!! Exactly what I needed. Now I can test the camera model and create the variables I need from the list based on which camera the image was created with. Our Canon’s EXIF data has stuff like shutter and aperture but our PhaseOne back is not integrated with the camera body so it can’t access lens settings etc. so I’ll prompt the user to enter them manually if the files came from that camera. Something like this


set myFile to (choose file)
tell application "GraphicConverter"
	try
		set ImgExif to (get file exif myFile)
		set {nameList, valueList} to {{}, {}}
		set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ","}
		repeat with i in ImgExif
			if text item 3 of i does not contain "Unknown" then
				set end of nameList to text item 3 of i
				set end of valueList to text item 4 of i
			end if
		end repeat
		set AppleScript's text item delimiters to ASTID
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no exif data"
	end try
end tell
--return nameList

-- Check the camera model
set cameraCheck to item 7 of valueList
--return cameraCheck

--Format EXIF info for the PhaseOne H 20
if cameraCheck = "H 20" then
	set camera_Model to (item 6 of valueList) & " - " & (item 7 of valueList)
	
	set aperture to the text returned of (display dialog ¬
		"Enter an aperture" default answer "f/" buttons {"Continue..."} default button 1)
	if aperture = "f/" or "f" or "" then
		set aperture to "N/A"
	end if
	
	set exposure_Time to the text returned of (display dialog ¬
		"Enter a shutter speed" default answer "1/" buttons {"Continue..."} default button 1)
	if exposure_Time = "1/" or "" then
		set exposure_Time to "N/A"
	end if
	
	
	set iso_Speed to the text returned of (display dialog ¬
		"Enter a ISO" default answer "" buttons {"Continue..."} default button 1)
	if iso_Speed = "" then
		set iso_Speed to "N/A"
	end if
	
	set lens_FocalLength to the text returned of (display dialog ¬
		"Enter the focal length of the lens" default answer " mm" buttons {"Continue..."} default button 1)
	if lens_FocalLength = " mm" then
		set lens_FocalLength to "N/A"
	end if
	
	--Format EXIF info for the Canon	
else if cameraCheck = "Canon EOS-1Ds" then
	set camera_Model to item 7 of valueList
	set exposure_Time to item 19 of valueList
	set aperture to item 20 of valueList
	set iso_Speed to item 22 of valueList
	set lens_FocalLength to item 30 of valueList
else
	display alert "Camera model not recognized." buttons {"Continue", "Cancel"} default button 1
end if

return {camera_Model, exposure_Time, aperture, lens_FocalLength, iso_Speed}

It’s still a work in progress of course. I’ve noticed the field order is different from a RAW file to the JPEG created from the RAW file. This script is actually for a RAW file but since I will be using this with JPEG’s I’ll have to adjust some of the item numbers called. Next step after this is to write the collected data into IPTC fields. Thanks to your help I’m on my way.

Thanks Again :smiley:

Stefan,

How can I modify this to run on every JPG in a chosen folder?


set myFile to (choose file without invisibles)

--Start repeat for each image in webFolder
--EXTRACT EXIF SECTION
tell application "GraphicConverter"
	try
		set ImgExif to (get file exif myFile)
		set {nameList, valueList} to {{}, {}}
		set {ASTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ","}
		repeat with i in ImgExif
			if text item 3 of i does not contain "Unknown" then
				set end of nameList to text item 3 of i
				set end of valueList to text item 4 of i
			end if
		end repeat
		set AppleScript's text item delimiters to ASTID
	on error number -2
		"the file contains no exif data"
	end try
	
	
	-- Check the camera model
	set cameraCheck to item 2 of valueList
	
	--Format EXIF info for the PhaseOne H 20
	if cameraCheck contains "H 20" then
		set camera_Model to (item 1 of valueList) & " - " & (item 2 of valueList)
		
		set aperture to the text returned of (display dialog ¬
			"Enter an aperture" default answer "f/" buttons {"Continue..."} default button 1)
		if aperture = "f/" or "f" or "" then
			set aperture to "N/A"
		end if
		
		set exposure_Time to the text returned of (display dialog ¬
			"Enter a shutter speed" default answer "1/" buttons {"Continue..."} default button 1)
		if exposure_Time = "1/" or "" then
			set exposure_Time to "N/A"
		end if
		
		
		set iso_Speed to the text returned of (display dialog ¬
			"Enter a ISO" default answer "" buttons {"Continue..."} default button 1)
		if iso_Speed = "" then
			set iso_Speed to "N/A"
		end if
		
		set lens_FocalLength to the text returned of (display dialog ¬
			"Enter the focal length of the lens" default answer " mm" buttons {"Continue..."} default button 1)
		if lens_FocalLength = " mm" then
			set lens_FocalLength to "N/A"
		end if
		
		
		--Format EXIF info for the Canon	
	else 
		set camera_Model to item 2 of valueList
		set exposure_Time to item 11 of valueList
		set aperture to "f/" & item 12 of valueList
		set iso_Speed to item 14 of valueList
		set lens_FocalLength to item 24 of valueList
	end if
	
	set expInfo to (camera_Model & " " & lens_FocalLength & " at " & exposure_Time & " @ " & aperture & " ISO-" & iso_Speed)
	
	--IPTC SECTION
	--Read the IPTC info from the image
	
	try
		get file iptc myFile
		set ImgIptc to result
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no iptc data"
	end try
	
	
	--Add the exposure information back to the image IPTC
	--Insert field determines which field the info will be placed
	(*
1 Caption
2 Caption Writer
3 Headline
4 Instructions
5 Byline (Photographer)
6 Byline Title
7 Credit
8 Source
9 Object Name
10 ??
11 City
12 State
13 Country Code
14 Original Reference
15 ??
16 ??
17 ??
18 Keywords
19 Copyright Notice
20 Creation Date
21 Creation Time
*)
	set insertField to "4"
	
	try
		set item (insertField) of ImgIptc to expInfo
		set file iptc of myFile to ImgIptc
		
	on error number -2
		-- This is the same string as is returned by 'get exiftext' when there's no such data.
		"the file contains no iptc data"
	end try
	
end tell
--End Repeat for each image
return ImgIptc

I would like to start it out something like


choose folder with prompt "Choose a job folder to proof to the web:" without invisibles
set jobFolder to result
set webFolder to ((jobFolder as string) & "Processed:Web_Proofs") as alias

Then have the script repeat on every JPEG in webFolder before moving on. I’m still struggling with file lists and repeats.

Thanks a bunch,
Mark

Hi Mark,

quick&dirty:

set jobFolder to (choose folder with prompt "Choose a job folder to proof to the web:" without invisibles)
set webFolder to ((jobFolder as string) & "Processed:Web_Proofs")
tell application "Finder" to repeat with myFile in (get items of folder webFolder whose name extension is in {"jpg", "jpeg"})
	my extract_exif_section(myFile as alias)
end repeat

and the handler

on extract_exif_section(myFile)
	tell application "GraphicConverter"
		try
...
...
		end try
	end tell
	return ImgIptc
end extract_exif_section

I don’t know, what kind of result has your routine (ImgIptc?)
If you want to keep every item use something like this:

set jobFolder to (choose folder with prompt "Choose a job folder to proof to the web:" without invisibles)
set webFolder to ((jobFolder as string) & "Processed:Web_Proofs")
set extractList to {}
tell application "Finder" to repeat with myFile in (get items of folder webFolder whose name extension is in {"jpg", "jpeg"})
	set end of extractList to my extract_exif_section(myFile as alias)
end repeat