Placing Multiple Images

If you have a need for speed, there is nothing like a couple of scripts to put your projects in high gear.

It seems that in today’s world, because computers have so much power, clients (and bosses) seem to think all one needs to do is wave a magic wand and the job is done. Little do many realize all the mind-numbing, little chores that are involved in putting a document (or project) together.

Placing and/or positioning multiple files in an InDesign document is one of those little chores that can eat up precious production time. If you are still doing it manually, you might want to consider automating the process with a script.

In our previous blog, the image files to be placed in a document were in a fixed folder location. The user selected the files to be placed from a list and the files were loaded to InDesign’s place gun for easy placement.

For this blog, we will look at another option for placing multiple files into a document. With this example, the files will be located in a folder named “images” inside the same folder as the target document.

The images are named using consecutive numbering that matches containers in the document. For example, the images are named “image1.psd”, “image2.psd”, and so on. The containers in the target document are named “image1”, “image2”,… to correspond.

The Script Outline

The outline for the script might read as follows:

  • verify a document is open; if so, place a reference to the document in a variable
  • get a list of all of the containers in the document whose name begins with “images” (containerList)
  • if the list is not empty, get a list of all images found in the images folder
  • then repeat with each of the items in the container list
  • if an image file exists whose name corresponds with that for the container, it is placed

Script Basics

At its simplest, the script could be written as follows:

   set imageName to "image" —name given to image containers
   set imageFolderName to "images"
   set fileNameExt to "psd"
   set badList to {} --list to hold references to containers that were not populated
   tell application "Adobe InDesign CC 2014"
      set docRef to document 1
      --get list of containers in document
      tell docRef
         set containerList to every rectangle whose name begins with imageName
      end tell
      --get path to folder for document
      if containerList is not {} then
         set docPath to (file path of docRef) as string
      end if
      --get list of files in folder; because we are using Finder, we will use a handler
      --call to handler, see handler below
      set imageFileList to my getImageFiles (docPath, fileNameExt, imageFolderName)
      --repeat through the list of containers and place the file if found
      repeat with i from 1 to length of containerList
         set itemName to name of item i of containerList
         set imageFileName to itemName & "." & fileNameExt
         if imageFileName is in imageFileList then
               set filealias to (docPath & imageFolderName & ":" & imageFileName) as alias
               set imageFrameRef to rectangle itemName of docRef
               tell imageFrameRef
                  place fileAlias without showing options
               end tell
            on error
               set end of badList to itemName
            end try
        end if 
      end repeat
end tell
if badList is not {} then
    display alert "Containers not populated:" & badList
end if
—-the Handler
(*returns list of image files found in folder referenced using docPath and folderName*)
on getImageFiles(docPath, fileNameExt, folderName)
	set imagePath to docPath & folderName
	tell application "Finder"
		set fileNames to name of every file of folder imagePath whose name extension is fileNameExt
	end tell
	return fileNames
end getImageFiles

For this to be a bullet-proof script, code needs to be added to make sure the script runs without error. Items to consider are:

  • make sure document is open
  • if measurements are used, make sure the measurements are set as anticipated
  • if styles are used, make sure the required styles are in the document

The Target Document

Of course, for this to work, the target document must be prepared with the image containers named as needed. Creating containers and giving them names may be almost as much work as just placing the images manually. So where does the time savings come into play?If saved as a template there is the possibility that it could be used multiple times with little modification. In creating the template, use a script to name the containers, and possibly assign object style and text styling. Below is an example of a simple template prepared with named containers to correspond with names of the image files.

There are even some circumstances where the script could also create the containers.An example is catalog pages where containers are created as a grid of rows and columns.

The next few blogs will be looking at issues and scripts involved in creating these and other templates.

Exending the Script

As long as you will be using a script, think of the ways it could do more than just place images.

Fit the images to the containers

   --add the following just after the statement that places fileAlias
   fit given fill proportionally
   fit given center content

Add Captions

If the image files have metadata defined, the captions for the files could be created as part of the script.

--add this just below the fit statements and before the end tell
   set theImage to image 1
   set theLink to item link of theImage
   set theXMP to link xmp of theLink
   set theString to description of theXMP
   --below the end tell statement, add
   if theString is not "" then
      set thePage to parent page of imageFrameRef
      copy geometric bounds of imageFrameRef to {y0, x0, y1, x1}
      tell thePage
         set frameRef to make text frame with properties {geometric bounds:{y1, x0, y1 + 60, x1}}
         set contents of frameRef to theString
      end tell
   end if 

Assign Object Style to Caption

Set the object style for the text frame created.

--at the top of the script define the name for the style and set its reference to missing
   set textObjStyleRef to missing value
   set textObjStyleName to "Caption"
   --inside the tell statement to the document add
      set textObjStyleRef to object style textObjStyleName
   end try
   (*the value for textObjStyleRef at this point will be either missing value or a reference to the style, so we test inside the tell statement to the page, right after creating the text frame*)
   if textObjStyleRef is not missing value then
      set applied object style of frameRef to textObjStyleRef
   end if

Fit the text frame to the text

Note that fit frame to content can be fussy, so we write the code instead

   --after setting the contents to the text frame
   set b to baseline of line -1 of frameRef
   set geometric bounds of frameRef to {y0, x0, b, y1}

Group the image frame and Caption frame

To make grouping an option, define a variable doGroup at the top of the script

   set doGroup to true
   --then after setting the contents of the text frame we can test for the value
   if doGroup is true then
      make group with properties {group items: {imageFrameRef, frameRef}}
   end if

That’s it. You might think of other things you would want your script to do. For instance, you might want to make sure the image frames comply with a given size or width-to-height ratio If the document is to be exported as an ePub, you may want to anchor the image containers.

Looking Forward

In our next blog we will introduce a script that can be used to help create a template with image and text frames named for automated placement.