You are not logged in.
Panic in the laboratory! On a Friday...
Just shortly after I entered my office this morning, my colleagues from the R&D lab approached me with a request to write an AppleScript for them. They needed to create image sequences from 3000 still images generated by a device measuring stress values in electroplated deposits and they definitely did not want to do that manually. Especially not on a Friday...
Applescript:
-- author: Martin Michel
-- created: 16.05.2008
-- requires:
-- • Mac OS X 10.5 Leopard
-- • QuickTime 7.2.1
-- This AppleScript will create an image sequence (QuickTime movie) from
-- selected or dropped image files.
--
-- The script will ask you to specify a file name and location for the new
-- QuickTime movie and lets you select specific settings for the image sequence
-- (frames per second/seconds per frame). Moreover you can choose to sort the
-- image files by their file names before creating the QuickTime movie.
--
-- The image sequence itself is created by a Python script using QTKit.
--
-- YOU DO NOT NEED QuickTime Pro to use this script :D
--
-- Supported image formats: jpg, jpeg, gif, png, tiff, tif, psd, pict, bmp, pdf
-- the AppleScript's name
property mytitle : "Sequimago"
-- I am called when the user opens the AppleScript with a double-click
on run
set finderitems to choose file with prompt "Please choose image files for the image sequence:" with multiple selections allowed without showing package contents and invisibles
my main(finderitems)
end run
-- I am called when the user drops Finder items onto the AppleScript's icon
on open finderitems
my main(finderitems)
end open
-- |--|--|--|--|--|--|--|--|--|--|--|--|--|
-- | Main Routine
-- |--|--|--|--|--|--|--|--|--|--|--|--|--|
-- I am the main function controlling the script flow
-- I demand a list of Finder items to process
on main(finderitems)
try
-- searching the given Finder items for image files that can be processes
set imgpaths to my getimgpaths(finderitems)
-- no image files found...
if imgpaths is {} then
set errmsg to "The dropped/selected items did not contain any image files to process." & return & return & "Supported image formats: jpg, jpeg, gif, png, tiff, tif, psd, pict, bmp, pdf"
my dsperrmsg(errmsg, "--")
return
end if
-- asking the user to provide a file path for the new QuickTime movie
set newmoviepath to my getnewmoviepath()
if newmoviepath is missing value then
return
end if
-- asking the user to select certain settings for the image sequence
set imgseqsettings to my getimgseqsettings()
if imgseqsettings is missing value then
return
end if
-- does the user want to sort the image files by their file names?
set sortimgfiles to my getsortimgfiles()
-- creating the image sequence
my crtimgsequence(newmoviepath, imgpaths, sortimgfiles, imgseqsettings)
-- catching unexpected errors
on error errmsg number errnum
my dsperrmsg(errmsg, errnum)
end try
end main
-- I am searching the given list of Finder items for image files
-- that can be used to create an image sequence
-- >>> I return a list of image file paths, that might be empty, if not image files are found
-- Note: I am currently searching for image files by simply looking at the file's name
-- extension. That is not the best approach...File types in the future?
on getimgpaths(finderitems)
set imgpaths to {}
repeat with finderitem in finderitems
set iteminfo to info for finderitem
if not folder of iteminfo then
set suffix to name extension of iteminfo
if suffix is not missing value then
if suffix is in {"jpg", "jpeg", "gif", "png", "tiff", "tif", "psd", "pict", "bmp", "pdf"} then
set imgpaths to imgpaths & (finderitem as Unicode text)
end if
end if
end if
end repeat
return imgpaths
end getimgpaths
-- I am asking the user to specify a file name and location for a new QuickTime movie
-- >>> I return the chosen file path as Unicode text [Mac path, not Posix path] or
-- >>> missing value in case the user cancels the dialog
on getnewmoviepath()
try
set newmoviepath to choose file name default name "imagesequence.mov" with prompt "Please specify a file name and location for the new QuickTime movie:"
return (newmoviepath as Unicode text)
on error
return missing value
end try
end getnewmoviepath
-- I am asking the user to select specific settings for the image sequence
-- (frames per second vs. seconds per frames)
-- >>> I return a special list containing a time code used by QuickTime
-- >>> {time value, time scale} or missing value in case the user cancels the dialog
on getimgseqsettings()
try
tell me
activate
display dialog "Please select a timing mode for the image sequence:" with title mytitle buttons {"Cancel", "Frames per second", "Seconds per frame"} default button 1
end tell
set dlgresult to result
if button returned of dlgresult is "Frames per second" then
set fpsvalue to my gettimingvalue("fps")
if fpsvalue is not missing value then
return {1, fpsvalue}
else
return missing value
end if
else if button returned of dlgresult is "Seconds per frame" then
set spfvalue to my gettimingvalue("spf")
if spfvalue is not missing value then
return {spfvalue, 1}
else
return missing value
end if
end if
on error
return missing value
end try
end getimgseqsettings
-- I am asking the user to enter the number of frames per second or the duration of
-- each frame in seconds based on the given mode ("fps" or "spf")
-- >>> I return a real or missing value in case the user cancels the dialog
on gettimingvalue(mode)
-- getting the system's decimal separator (comma or dot)
set decseparator to my getdecseparator()
if mode is "fps" then
set dlgmsg to "Please enter the number of desired frames per second:" & return & "(decimal separator: »" & decseparator & "«)"
else
set dlgmsg to "Please enter the duration of each frame in seconds:" & return & "(decimal separator: »" & decseparator & "«)"
end if
set defansw to "1" & decseparator & "0"
try
tell me
activate
display dialog dlgmsg default answer defansw buttons {"Cancel", "Enter"} default button 2 with title mytitle
end tell
set dlgresult to result
set usrinput to text returned of dlgresult
-- no input, empty string
if usrinput is "" then
my gettimingvalue(mode)
else
-- can we convert the user input into a real?
try
set fpsvalue to usrinput as real
if fpsvalue is greater than 0 then
return fpsvalue
end if
on error errmsg number errnum
-- no, we cannot...try again
my dsperrmsg(errmsg, errnum)
my getfpsvalue()
end try
end if
on error
return missing value
end try
end gettimingvalue
-- I am asking the user if he wants to sort the image files by their file names
-- before creating the image sequence
-- >>> I return true or false
on getsortimgfiles()
tell me
activate
display dialog "Do you want to sort the image files by their file names before processing them?" buttons {"Yes", "No"} default button 2 with icon note with title mytitle
end tell
set dlgresult to result
if button returned of dlgresult is "No" then
return false
else if button returned of dlgresult is "Yes" then
return true
end if
end getsortimgfiles
-- I am creating an image sequence using the given parameters and a Python script
on crtimgsequence(newmoviepath, imgpaths, sortimgfiles, imgseqsettings)
-- file path of the Python script responsible for creating the image sequence
-- using the QTKit and the newly introduced Scripting Bridge
set mypath to ((path to me) as Unicode text)
set pyscriptpath to POSIX path of (mypath & "Contents:Resources:crtimgseq.py")
-- we need to use a dot as the decimal separator when passing these two real numbers
-- to the Python script on the command line, therefore we search and replace any commas
set timevalue to my searchnreplace(",", ".", (item 1 of imgseqsettings) as Unicode text)
set timescale to my searchnreplace(",", ".", (item 2 of imgseqsettings) as Unicode text)
set newmoviepath to (POSIX path of newmoviepath)
-- creating a large string containing all image file paths, so that we can easily
-- pass them on to the Python script
set strpaths to ""
repeat with imgpath in imgpaths
set strpaths to strpaths & space & quoted form of (POSIX path of imgpath)
end repeat
-- creating the complete command
set command to "python " & quoted form of pyscriptpath & space & quoted form of newmoviepath & space & timevalue & space & timescale & space & sortimgfiles & strpaths
log command
set command to command as «class utf8»
-- there we go...BUMM
do shell script command
end crtimgsequence
-- I am returning the currently used decimal separator
on getdecseparator()
set strnum to 0.1 as Unicode text
set decseparator to character 2 of strnum
return decseparator
end getdecseparator
-- I am returning the text items of the given text (delimited by the given delimiter)
on gettxtitems(txt, delchar)
considering case, diacriticals and punctuation
set olddelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to {delchar}
set txtitems to text items of txt
set AppleScript's text item delimiters to olddelims
end considering
return txtitems
end gettxtitems
-- I am a very old search & replace function
on searchnreplace(searchstr, replacestr, txt)
considering case, diacriticals and punctuation
if txt contains searchstr then
set olddelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to {searchstr}
set txtitems to text items of txt
set AppleScript's text item delimiters to {replacestr}
set txt to txtitems as Unicode text
set AppleScript's text item delimiters to olddelims
end if
end considering
return txt
end searchnreplace
-- I am displaying error messages to the user
on dsperrmsg(errmsg, errnum)
tell me
activate
display dialog "Sorry, an error occured:" & return & return & (errmsg & " (" & errnum & ")") buttons {"OK"} default button 1 with icon stop with title mytitle giving up after 60
end tell
end dsperrmsg
Plonum - Convert images to iWork Numbers documents
Offline
Thansk a ton! I incorporated some of your script in to a Photoshop script I've been playing around with.
This really helped me a ton!
Offline
Sorry to bother, but for me, I can't use it. I use snow leopard and when I use it everything seems to go fine until I open it and it is less then a billionth of a second. No error pops up, nothing. Help!
Computer engineer by day, lazy developer by night.
Offline
Hi,
I am also on Snow Leopard and the script works on my MacBook Pro (Intel). Maybe you need to open it in Script Editor, compile it and then save it again?
Best regards,
Martin
Plonum - Convert images to iWork Numbers documents
Offline
Hi, your script is great but it seems to stop before the end of my image sequence.
My image sequence is 2000 frames long but the QT file is only 565 frames after it compiles it.
I tried it with both sorting enabled and disabled and had the same result.
I tried it on a different image sequence which were smaller frames and it worked great and did 3000 frames.
I tried another large sized tiff sequence and I get the same issue, it stops at around frame 565.
I then tried the same sequence but this time I used compressed TIff files instead of uncompressed, thinking it could be a file size issue but it still stops at 565.
The files are 1920x1080 Tiff files, and the one that worked were 720x480 Tiff files.
After more investigation, it must be a memory issue as I tried some files that were 1280x720 and it stopped at 1298 out of 3000.
I have uploaded a 25mb zip file with 2700 tiff files if you would like to test it at your end.
http://dl.dropbox.com/u/4031669/TiffSeq.zip
Thanks.
Phil
Offline
Hi Phil,
I had a hard time fixing this bug, but finally found a solution.
First I rewrote the underlying tool in Obj-C, because I thought that PyObjC might have some memory release problems. But also the Obj-C tool always had a significant performance hit when it reached 600 processed images. I tried many things, even splitting up the process in creating different movies, but nothing helped.
Then I stumbled across this thread and immediately the problem was gone. Just adding an autorelease pool to the loop adding the images fixed the problem. Now the whole process seems to run a lot faster, with much less memory usage and also all 2698 images are processed.
I created a beta version of the updated Sequimago AppleScript, which you can download here. Please try it and let me know what you think:
Plonum - Convert images to iWork Numbers documents
Offline
Hi Martin,
erst einmal vielen Dank für das tolle Skript! Hat meine 2800 Fotos gerade super gewandelt und mir viel geld gespart! ;o)
Ein was ist mir noch aufgefallen, je länger das Skrit läuft, desto langsamer "wandelt" es die Bilder. Liegt das an QuickTime und der wachsenden *.mov Größe, oder gibt es noch ein Memory-Leak?
Vielen Dank für das Skript! )
LG André
Offline
Hi Martin,
Ein was ist mir noch aufgefallen, je länger das Skrit läuft, desto langsamer "wandelt" es die Bilder. Liegt das an QuickTime und der wachsenden *.mov Größe, oder gibt es noch ein Memory-Leak?
Hallo André,
gut zu wissen, daß Menschen das Skript tatsächlich gut gebrauchen können
Hast Du die Version 1.1b verwendet, die man hier findet?
Dort sollte der Fehler eigentlich behoben sein...
Viele Grüße aus dem regenreichen Berlin
Martin
Plonum - Convert images to iWork Numbers documents
Offline
Love the script. I wonder if you could add an option for some simple transitions.
Offline
Hi,
Just a simple question : I've tried to modify the script to load all pictures in a selected folder :
Applescript:
on run
set Afolder to choose folder with prompt "Please select directory."
tell application "Finder"
set finderitems to every item in Afolder
end tell
my main(finderitems)
end run
But it doesn't work. Any idea why ?
Offline
Hi Martin, all
what an excellent program, many thanks! I'm trying to use it from a shell script (I had a look at how you're calling the imgsequence binary) but I'm not really sure what's happening here. I can make a movie without problems as long as I specify both -ts and -tv and both are 1... however, 1fps is not really what I want. When I only specify fps (so -ts 1 for 1 fps), the resulting video is corrupt. Same goes for if I only specify -tv. Specifying anything other than 1 for -tv or -ts results in a corrupted video file as well. Do you have any recommendations on how to call this to create a 10fps movie?
Many thanks
- Balt
Edit: This is how I call imgsequence for a 1fps movie which works:
imgsequence -mov imagesequence.mov -sort 0 -ts 1 -tv 1 -imgs 'east1369017271.jpg|east1369017391.jpg'
Last edited by balt (2013-05-19 08:38:11 pm)
Offline
Hi Balt,
I just downloaded Sequimago 1.1b and used the imgsequence binary from the package contents like follows to successfully create a 10fps movie:
/Users/martin/Downloads/Sequimago\ 1.1b.1/Sequimago.app/Contents/Resources/imgsequence -mov /Users/martin/Desktop/test.mov -sort 0 -ts 10.0 -tv 1.0 -imgs "/Users/martin/Desktop/Neuer Ordner/0.JPG|/Users/martin/Desktop/Neuer Ordner/1.JPG|/Users/martin/Desktop/Neuer Ordner/2.JPG|/Users/martin/Desktop/Neuer Ordner/3.JPG|/Users/martin/Desktop/Neuer Ordner/4.JPG|/Users/martin/Desktop/Neuer Ordner/5.JPG|/Users/martin/Desktop/Neuer Ordner/6.JPG|/Users/martin/Desktop/Neuer Ordner/7.JPG|/Users/martin/Desktop/Neuer Ordner/8.JPG|/Users/martin/Desktop/Neuer Ordner/9.JPG|/Users/martin/Desktop/Neuer Ordner/10.JPG|/Users/martin/Desktop/Neuer Ordner/11.JPG|/Users/martin/Desktop/Neuer Ordner/12.JPG|/Users/martin/Desktop/Neuer Ordner/13.JPG|/Users/martin/Desktop/Neuer Ordner/14.JPG|/Users/martin/Desktop/Neuer Ordner/15.JPG|/Users/martin/Desktop/Neuer Ordner/16.JPG|/Users/martin/Desktop/Neuer Ordner/17.JPG"
Do your images all have the same size?
I used the imgsequence binary on a MacBook Pro 2.4 GHz Intel Core 2 Duo running Mac OS X 10.8.3
Best regards from Berlin,
Martin
Plonum - Convert images to iWork Numbers documents
Offline
Hi Martin,
thanks for picking up on this.
All my images are the same indeed, just a series of frames from a webcam. I have to use the arguments the other way around than you show. To make a 10fps movie: -ts 1.0 -tv 10.0
Cheers from Sydney
- Balt
Offline
Hi Martin,
This is an awesome application! Thanks so much!!
Tim
Offline