INdesign contact sheet script
INdesign contact sheet script
A simple way to make contact sheets in InDesign
Friday, January 20, 2012
When I worked for Leo Burnett, we often would get requests from art directors for a contact sheet of images. When InDesign was still in it’s infancy, there weren’t a lot of plugins around and the Creative Suite (CS1!) had just been released. These were a pain to build manually so I figured a script would be a good way to automate the process. The images would be uniform, and the script would knock it out in a few moments, instead of the hour or more to do it manually.
Along the way I learned how wonderfully scriptable InDesign is and how helpful the AdobeForums could be. I submitted many questions to the boards, and received so much help I was compelled to post my finished work up for the group to use. I figured the collective effort had really made the script what it was and so the collective group should have access to it.
I updated it for CS2 and when CS3 was just about to be released, we had a demo from our local Adobe guy, Tom Petrillo. He showed all the features, and then proceeded to show some goodies including this “brand new” script that would make a proof sheet of images. I was shocked and then amused. It turned out that some engineer at Adobe cleaned up my script and made it VBScript and Javascript compatible and released it on their installer CD.
When CS4 came out, I was busy and didn’t bother to update the script. However some enterprising individual decided to release a $20 version. Recently I had a client request again to make a proof sheet of images for a art director. The more things change... So I fired up Script Debugger and updated it to CS5, and then also added the ability to include several types of metadata including custom XMP metadata. While I built this intending for the custom metadata to come from Xinet, you can edit the script to use any custom namespace. You will however need to install ExifTool from here if you want custom XMP.
--ImageCatalog.as
--An InDesign CS AppleScript by Rich Carroll with tremendous help from the Adobe Forums
--
--Creates an image catalog from the graphics files in a selected folder.
--
--For more on InDesign scripting, go to http://www.adobe.com/products/indesign/scripting.html
--or visit the InDesign Scripting forum at http://www.adobeforums.com
--
global myFolder
global myCurrentFile
set oldHViewPrefs to ""
set oldVViewPrefs to ""
set myExtensions to {"tif", "tiff", "jpg", "jpeg", "gif", "eps", "ps", "psd", "ai", "pdf", “png”}
set myFileList to {}
set myFolder to choose folder with prompt "Select the folder containing the graphics you want to place"
tell application "Finder"
set sortedFiles to {}
set myFiles to list folder myFolder without invisibles
repeat with myFile in myFiles
set temp to properties of ((myFolder as string) & myFile as alias)
if class of temp is document file then
set sortedFiles to sortedFiles & myFile
end if
end repeat
set myFiles to sortedFiles
end tell
--Build a list of graphics files in the folder.
repeat with myCounter from 1 to count of items in myFiles
set myFile to item myCounter of myFiles
try
tell application "Finder"
set myFileType to file type of (((myFolder as string) & myFile) as alias) --myFile
end tell
end try
--set theName to the name of myFile
set myFileTypes to {"JPEG", "EPSF", "PICT", "TIFF", "8BPs", "GIFf", "PDF "}
--tests file type of current file against entire list of possibilities in one operation.
if myFileTypes contains myFileType then
copy myFile to end of myFileList
else if myFileType is missing value or myFileType is "TEXT" then
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set currentExt to text item -1 of myFile
if myExtensions contains currentExt then
copy myFile to end of myFileList
end if
set AppleScript's text item delimiters to oldTID
end if
end repeat
if (count myFileList) > 0 then
myDisplayDialog(myFileList, myFolder)
display dialog "Done!"
else if (count myFileList) = 0 then
display dialog "No valid files found"
end if
--show the dialog
on myDisplayDialog(myFiles, myFolder)
set myLabelWidth to 132
tell application "Adobe InDesign CS5.5"
set myDialog to make dialog with properties {name:"ImageCatalog"}
tell myDialog
tell (make dialog column)
tell (make dialog row)
make static text with properties {static label:"Information"}
end tell
tell (make border panel)
tell (make dialog column)
tell (make dialog row)
make static text with properties {static label:"SourceFolder:", min width:myLabelWidth}
make static text with properties {static label:myFolder, min width:myLabelWidth}
end tell
tell (make dialog row)
make static text with properties {static label:"Number of Graphics:", min width:myLabelWidth}
make static text with properties {static label:((count myFiles) as string)}
end tell
end tell
end tell
tell (make dialog row)
make static text with properties {static label:"Options"}
end tell
tell (make border panel)
tell (make dialog column)
tell (make dialog row)
make static text with properties {static label:"Number of Rows:", min width:myLabelWidth}
set myNumberOfRowsField to make integer editbox with properties {edit value:3}
end tell
tell (make dialog row)
make static text with properties {static label:"Number of Columns:", min width:myLabelWidth}
set myNumberOfColumnsField to make integer editbox with properties {edit value:3}
end tell
tell (make dialog row)
make static text with properties {static label:"Vertical Offset:", min width:myLabelWidth}
set myVerticalOffsetField to make measurement editbox with properties {edit value:12, edit units:points}
end tell
tell (make dialog row)
make static text with properties {static label:"Horizontal Offset:", min width:myLabelWidth}
set myHorizontalOffsetField to make measurement editbox with properties {edit value:12, edit units:points}
end tell
tell (make dialog row)
tell (make dialog column)
make static text with properties {static label:"Page Size:", min width:myLabelWidth}
end tell
tell (make dialog column)
set myPageSizeButtons to make radiobutton group
tell myPageSizeButtons
make radiobutton control with properties {static label:"Letter Portrait", checked state:true}
make radiobutton control with properties {static label:"Letter Landscape", checked state:false}
make radiobutton control with properties {static label:"Tabloid Portrait", checked state:false}
make radiobutton control with properties {static label:"Tabloid Landscape", checked state:false}
make radiobutton control with properties {static label:"A4 Portrait", checked state:false}
make radiobutton control with properties {static label:"A4 Landscape", checked state:false}
end tell
end tell
end tell
tell (make dialog row)
tell (make dialog column)
make static text with properties {static label:"Label:", min width:myLabelWidth}
end tell
tell (make dialog column)
set FileNameCheckbox to make checkbox control with properties {static label:"Filename", checked state:true}
set FilePathCheckbox to make checkbox control with properties {static label:"File path", checked state:false}
set FileImageInfoCheckbox to make checkbox control with properties {static label:"ImageInfo", checked state:false}
set XinetInfoCheckbox to make checkbox control with properties {static label:"Custom metadata", checked state:false}
end tell
end tell
tell (make dialog row)
tell (make dialog column)
make static text with properties {static label:"Fitting:", min width:myLabelWidth}
end tell
tell (make dialog column)
set myFitProportionalCheckbox to make checkbox control with properties {static label:"Proportional", checked state:true}
set myFitCenterContentCheckbox to make checkbox control with properties {static label:"Center Content", checked state:true}
set myFitFrameToContentCheckbox to make checkbox control with properties {static label:"FrameToContent", checked state:true}
end tell
end tell
tell (make dialog row)
set myRemoveEmptyFramesCheckbox to make checkbox control with properties {static label:"Remove Empty Frames", checked state:true}
end tell
end tell
end tell
end tell
end tell
set myResult to show myDialog
if myResult = true then
set myNumberOfRows to edit value of myNumberOfRowsField
set myNumberOfColumns to edit value of myNumberOfColumnsField
set myVerticalOffset to edit value of myVerticalOffsetField
set myHorizontalOffset to edit value of myHorizontalOffsetField
set myPageSize to selected button of myPageSizeButtons
--set myLabels to selected button of myLabelsButtons
set FileNameCheckbox to checked state of FileNameCheckbox
set FilePathCheckbox to checked state of FilePathCheckbox
set FileImageInfoCheckbox to checked state of FileImageInfoCheckbox
set XinetInfoCheckbox to checked state of XinetInfoCheckbox
set myFitProportional to checked state of myFitProportionalCheckbox
set myFitCenterContent to checked state of myFitCenterContentCheckbox
set myFitFrameToContent to checked state of myFitFrameToContentCheckbox
set myRemoveEmptyFrames to checked state of myRemoveEmptyFramesCheckbox
--set myXWNVprefix to edit value of myXinetOptions
my myMakeImageCatalog(myFiles, myNumberOfRows, myNumberOfColumns, myPageSize, myRemoveEmptyFrames, myVerticalOffset, myHorizontalOffset, FileNameCheckbox, FilePathCheckbox, FileImageInfoCheckbox, XinetInfoCheckbox, myFitProportional, myFitCenterContent, myFitFrameToContent)
end if
destroy myDialog
end tell
end myDisplayDialog
on myMakeImageCatalog(myFiles, myNumberOfRows, myNumberOfColumns, myPageSize, myRemoveEmptyFrames, myVerticalOffset, myHorizontalOffset, myFitProportional, myFitCenterContent, myFitFrameToContent, FileNameCheckbox, FilePathCheckbox, FileImageInfoCheckbox, XinetInfoCheckbox)
set oldDelims to AppleScript's text item delimiters
tell application "Adobe InDesign CS5.5"
set myFramesPerPage to myNumberOfRows * myNumberOfColumns
set myDocument to make document
set oldVViewPrefs to vertical measurement units of view preferences of myDocument
set oldHViewPrefs to horizontal measurement units of view preferences of myDocument
if myPageSize is less than 4 then
set horizontal measurement units of view preferences of myDocument to points
set vertical measurement units of view preferences of myDocument to points
else if myPageSize is greater than 3 then
set horizontal measurement units of view preferences of myDocument to millimeters
set vertical measurement units of view preferences of myDocument to millimeters
end if
if myPageSize is 0 then
set properties of document preferences of myDocument to {page width:612, page height:792}
else if myPageSize is 1 then
set properties of document preferences of myDocument to {page width:792, page height:612}
else if myPageSize is 2 then
set properties of document preferences of myDocument to {page width:792, page height:1224}
else if myPageSize is 3 then
set properties of document preferences of myDocument to {page width:1224, page height:792}
else if myPageSize is 4 then
set properties of document preferences of myDocument to {page width:210, page height:297}
else if myPageSize is 5 then
set properties of document preferences of myDocument to {page width:297, page height:210}
end if
set myDocumentPreferences to document preferences of myDocument
set myNumberOfFrames to (count myFiles)
set myNumberOfPages to ((myNumberOfFrames / myFramesPerPage) as string)
if ((myNumberOfPages * myFramesPerPage) < myNumberOfFrames) then
set myNumberOfPages to myNumberOfPages + 1
end if
set myNumberOfPages to myNumberOfPages as number
set myNumberOfPages to round myNumberOfPages
set pages per document of myDocumentPreferences to myNumberOfPages
set facing pages of myDocumentPreferences to false
set myPage to page 1 of myDocument
set myMarginPreferences to margin preferences of myPage
set myLeftMargin to left of myMarginPreferences
set myTopMargin to top of myMarginPreferences
set myRightMargin to right of myMarginPreferences
set myBottomMargin to bottom of myMarginPreferences
set myLiveWidth to ((page width of myDocumentPreferences) - (myLeftMargin + myRightMargin)) + myHorizontalOffset
set myLiveHeight to (page height of myDocumentPreferences) - (myTopMargin + myBottomMargin)
set myColumnWidth to myLiveWidth / myNumberOfColumns
set myFrameWidth to myColumnWidth - myHorizontalOffset
set myRowHeight to (myLiveHeight / myNumberOfRows)
set myFrameHeight to myRowHeight - myVerticalOffset
try
set myLabelStyle to paragraph style "Labels" of myDocument
on error
tell myDocument
set myLabelStyle to make new paragraph style with properties {name:"Labels", point size:8}
end tell
end try
try
set myLabelLayer to layer "Labels" of myDocument
on error
tell myDocument
set myLabelLayer to make layer with properties {name:"Labels"}
end tell
end try
--Construct the frames in reverse order. This will save us time later (when we place the graphics).
repeat with myCounter from (count pages of myDocument) to 1 by -1
set myPage to page myCounter of myDocument
repeat with myRowCounter from (myNumberOfRows - 1) to 0 by -1
set myY1 to myTopMargin + (myRowHeight * myRowCounter)
set myY2 to myY1 + myFrameHeight
repeat with myColumnCounter from (myNumberOfColumns - 1) to 0 by -1
set myX1 to myLeftMargin + (myColumnWidth * myColumnCounter)
set myX2 to myX1 + myFrameWidth
tell myPage to make rectangle with properties {geometric bounds:{myY1, myX1, myY2, myX2}, stroke weight:0, stroke color:swatch "None" of myDocument, item layer:layer -1 of myDocument}
end repeat
end repeat
end repeat
--Because we constructed the frames in reverse order, rectangle 1 is the first rectangle on page 1, so we can simply iterate through
--the rectangles, placing a file in each one in turn.
repeat with myCounter from 1 to myNumberOfFrames
set myFile to item myCounter of myFiles
set myRectangle to rectangle myCounter of myDocument
tell myRectangle
set myCurrentFile to place (((myFolder as string) & myFile) as alias)
set theFilePath to POSIX path of (((myFolder as string) & myFile) as alias)
set myCurrentFile to item 1 of myCurrentFile
set myCurrentFileProps to properties of myCurrentFile
try
set myFilePPI to actual ppi of myCurrentFile
end try
set geoBounds to (geometric bounds of (properties of (object reference of myCurrentFile)))
set label to myFile as string
if myFitProportional is true then
fit given proportionally
end if
if myFitCenterContent is true then
fit given center content
end if
if myFitFrameToContent is true then
fit given frame to content
end if
end tell
set AppleScript's text item delimiters to return
if FileNameCheckbox is not equal to 0 then
set labelContent to myFile as string
end if
if FilePathCheckbox is not equal to 0 then
set labelContent to labelContent & return & ((myFolder as string) & myFile) as string
end if
if FileImageInfoCheckbox is not equal to 0 then
try
set myWidth to (((item 4 of geoBounds) - (item 2 of geoBounds)) / 72) * 1000
set myHeight to (((item 3 of geoBounds) - (item 1 of geoBounds)) / 72) * 1000
set myWidth to (round myWidth) / 1000
set myHeight to (round myHeight) / 1000
set myLabelString to (myFile & " is " & myWidth & " inches x " & myHeight & " inches @ " & (item 1 of myFilePPI) & " ppi") as string
set labelContent to labelContent & return & myLabelString
on error
set labelContent to labelContent & return & (myFile & " (resolution info missing)") as string
end try
end if
if XinetInfoCheckbox is not equal to 0 then
try
--additions here for MD enhancement
--must enter correct path to the Exif tool here
--ExifTool can be found here http://www.sno.phy.queensu.ca/~phil/exiftool/
set exiftoolPath to POSIX path of "/Applications/Image-ExifTool-8.69/exiftool" as string
set AppleScript's text item delimiters to ""
set theShellCommand to exiftoolPath & " -XMP -b" & " " & theFilePath
set theXMPcontents to do shell script theShellCommand
-- now we parse the data for Custom MD
set AppleScript's text item delimiters to return
set theXMPcontents to every text item in theXMPcontents
set XinetMDValues to "" as string
--the correct metadatafield prefix will need to be entered here, include leading spaces please. Currently a Xinet DAM example is being used
set XWNVprefix to " xwnv:Description="
repeat with myItem in theXMPcontents
if myItem contains XWNVprefix then
set myItem to myItem as string
copy myItem to XinetMDValues
end if
end repeat
set AppleScript's text item delimiters to XWNVprefix
set XinetMDValue to every text item in XinetMDValues
set XinetMDValue to text item 2 of XinetMDValue
set AppleScript's text item delimiters to " "
set XinetMDValue to words 1 through end of XinetMDValue as string
set labelContent to labelContent & return & XinetMDValue
--end additionsfor MD enhancement
end try
end if
set myX1 to item 2 of geometric bounds of myRectangle
set myBounds to geometric bounds of myRectangle
set myY1 to item 3 of myBounds
set myX2 to item 4 of myBounds
set myY2 to (item 3 of myBounds) + myVerticalOffset
set labelContent to labelContent & return
tell parent of myRectangle
set myTextFrame to make text frame with properties {geometric bounds:{myY1, myX1, myY2, myX2}, contents:labelContent, item layer:myLabelLayer}
tell myTextFrame
set applied paragraph style of text 1 to myLabelStyle
end tell
end tell
end repeat
--Remove any empty frames.
if myRemoveEmptyFrames is true then
try
tell myDocument
tell (every rectangle whose content type is unassigned) to delete
end tell
end try
end if
tell myDocument
set horizontal measurement units of view preferences of myDocument to oldHViewPrefs
set vertical measurement units of view preferences of myDocument to oldVViewPrefs
end tell
end tell
set AppleScript's text item delimiters to oldDelims
end myMakeImageCatalog
A simple script to make a contact sheet, or proof sheet in InDesign instead of Photoshop