• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Image Catalog script crashes InDesign 2020

Community Beginner ,
Aug 04, 2020 Aug 04, 2020

Copy link to clipboard

Copied

Our team uses the Image Catalog script to generate contact sheets of photos for our client. We've used it for years and never had a problem. I tried running the script today and it crashed InDesign in three instances. The photos will start populating on the page as normal, but after a few minutes, InDesign freezes and then I get the error message that InDesign has stopped working. When I re-open Indesign, the previous file pops up showing photo thumbs on the first page, and photo boxes on the rest of the pages. It looks like the script was able to generate the appropriate number of pages for the photo thumb layout, as well as photo boxes before it crashes. So it seems the script is encountering something that makes it crash.
I've searched online but could not find any answers. Any help or tips will be appreciated. We can't live without this script. Thanks!

TOPICS
Bug , Performance , Scripting

Views

266

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Aug 04, 2020 Aug 04, 2020

Not sure what could be causing the error, but it sounds like it probably is failing during the Place routine. I added a try/catch block that will alert any error during that part of the routine, and skip that image and move on to the next. Try running this script and let me know if you receive any errors. 

 

 

//ImageCatalog.jsx
//An InDesign JavaScript 
/*  
@@@BUILDINFO@@@ "ImageCatalog.jsx" 3.0.0 15 December 2009
*/ 
//Creates an image catalog from the graphic files in a selected folder. 
//E
...

Votes

Translate

Translate
Community Expert ,
Aug 04, 2020 Aug 04, 2020

Copy link to clipboard

Copied

Not sure what could be causing the error, but it sounds like it probably is failing during the Place routine. I added a try/catch block that will alert any error during that part of the routine, and skip that image and move on to the next. Try running this script and let me know if you receive any errors. 

 

 

//ImageCatalog.jsx
//An InDesign JavaScript 
/*  
@@@BUILDINFO@@@ "ImageCatalog.jsx" 3.0.0 15 December 2009
*/ 
//Creates an image catalog from the graphic files in a selected folder. 
//Each file can be labeled with the file name, and the labels are placed on 
//a separate layer and formatted using a paragraph style ("label") you can 
//modify to change the appearance of the labels. 
// 
//For more on InDesign/InCopy scripting see the documentation included in the Scripting SDK 
//available at http://www.adobe.com/devnet/indesign/sdk.html
//Or visit the InDesign Scripting User to User forum at http://www.adobeforums.com . 
// 
//The myExtensions array contains the extensions of the graphic file types you want 
//to include in the catalog. You can remove extensions from or add extensions to this list. 
//myExtensions is a global. Mac OS users should also look at the file types in the myFileFilter function.
main();
function main(){
	var myFilteredFiles;
	//Make certain that user interaction (display of dialogs, etc.) is turned on.
	app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
	myExtensions = [".jpg", ".jpeg", ".eps", ".ps", ".pdf", ".tif", ".tiff", ".gif", ".psd", ".ai"] 
	//Display the folder browser. 
	var myFolder = Folder.selectDialog("Select the folder containing the images", ""); 
	//Get the path to the folder containing the files you want to place. 
	if(myFolder != null){ 
			if(File.fs == "Macintosh"){
				myFilteredFiles = myMacOSFileFilter(myFolder);
			}
			else{
				myFilteredFiles = myWinOSFileFilter(myFolder);
			}
			if(myFilteredFiles.length != 0){ 
					myDisplayDialog(myFilteredFiles, myFolder); 
					alert("Done!");
			} 
	}
}
//Windows version of the file filter.
function myWinOSFileFilter(myFolder){
	var myFiles = new Array;
	var myFilteredFiles = new Array; 
	for(myExtensionCounter = 0; myExtensionCounter < myExtensions.length; myExtensionCounter++){ 
		myExtension = myExtensions[myExtensionCounter]; 
        myFiles = myFolder.getFiles("*"+ myExtension); 
		if(myFiles.length != 0){ 
			for(var myFileCounter = 0; myFileCounter < myFiles.length; myFileCounter++){ 
				myFilteredFiles.push(myFiles[myFileCounter]); 
			} 
		} 
	}	
	return myFilteredFiles;
}
function myMacOSFileFilter(myFolder){
	var myFilteredFiles = myFolder.getFiles(myFileFilter);
	return myFilteredFiles;
}
//Mac OS version of file filter
//Have to provide a separate version because not all Mac OS users use file extensions
//and/or file extensions are sometimes hidden by the Finder.
function myFileFilter(myFile){
	var myFileType = myFile.type;
	switch (myFileType){
		case "JPEG":
		case "EPSF":
		case "PICT":
		case "TIFF":
		case "8BPS":
		case "GIFf":
		case "PDF ":
			return true;
			break;
		default:
		for(var myCounter = 0; myCounter<myExtensions.length; myCounter++){
			var myExtension = myExtensions[myCounter]; 	
			if(myFile.name.indexOf(myExtension)>-1){
				return true;
				break;			
			}
		}
	}
	return false;	
}
function myDisplayDialog(myFiles, myFolder){ 
	var myLabelWidth = 112; 
	var myStyleNames = myGetParagraphStyleNames(app);
	var myLayerNames = ["Layer 1", "Labels"];
	var myDialog = app.dialogs.add({name:"Image Catalog"}); 
	with(myDialog.dialogColumns.add()){
		with(dialogRows.add()){ 
			staticTexts.add({staticLabel:"Information:"}); 
		}
		with(borderPanels.add()){
			with(dialogColumns.add()){
				with(dialogRows.add()){ 
					staticTexts.add({staticLabel:"Source Folder:", minWidth:myLabelWidth}); 
					staticTexts.add({staticLabel:myFolder.path + "/" + myFolder.name}); 
				} 
				with(dialogRows.add()){ 
					staticTexts.add({staticLabel:"Number of Images:", minWidth:myLabelWidth}); 
					staticTexts.add({staticLabel:myFiles.length + ""}); 
				} 
			}
		}
		with(dialogRows.add()){ 
				staticTexts.add({staticLabel:"Options:"}); 
		} 
		with(borderPanels.add()){
			with(dialogColumns.add()){
				with(dialogRows.add()){
					staticTexts.add({staticLabel:"Number of Rows:", minWidth:myLabelWidth}); 
					var myNumberOfRowsField = integerEditboxes.add({editValue:3}); 
				} 
				with(dialogRows.add()){ 
					staticTexts.add({staticLabel:"Number of Columns:", minWidth:myLabelWidth}); 
					var myNumberOfColumnsField = integerEditboxes.add({editValue:3}); 
				} 
				with(dialogRows.add()){ 
					staticTexts.add({staticLabel:"Horizontal Offset:", minWidth:myLabelWidth}); 
					var myHorizontalOffsetField = measurementEditboxes.add({editValue:12, editUnits:MeasurementUnits.points}); 
				} 
				with(dialogRows.add()){ 
					staticTexts.add({staticLabel:"Vertical Offset:", minWidth:myLabelWidth}); 
					var myVerticalOffsetField = measurementEditboxes.add({editValue:24, editUnits:MeasurementUnits.points}); 
				} 
				with (dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Fitting:", minWidth:myLabelWidth}); 
					}
					with(dialogColumns.add()){
						var myFitProportionalCheckbox = checkboxControls.add({staticLabel:"Proportional", checkedState:true});
						var myFitCenterContentCheckbox = checkboxControls.add({staticLabel:"Center Content", checkedState:true});
						var myFitFrameToContentCheckbox = checkboxControls.add({staticLabel:"Frame to Content", checkedState:true});
					}
				}
				with(dialogRows.add()){ 
						var myRemoveEmptyFramesCheckbox = checkboxControls.add({staticLabel:"Remove Empty Frames:", checkedState:true}); 
				}
			}
		}
		with(dialogRows.add()){ 
				staticTexts.add({staticLabel:""}); 
		} 
		var myLabelsGroup = enablingGroups.add({staticLabel:"Labels", checkedState:true});
		with (myLabelsGroup){
			with(dialogColumns.add()){
				//Label type
				with(dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Label Type:", minWidth:myLabelWidth});
					}
					with(dialogColumns.add()){
						var myLabelTypeDropdown = dropdowns.add({stringList:["File name", "File path", "XMP description", "XMP author"], selectedIndex:0});
					}
				}
				//Text frame height
				with(dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Label Height:", minWidth:myLabelWidth});
					}
					with(dialogColumns.add()){
						var myLabelHeightField = measurementEditboxes.add({editValue:24, editUnits:MeasurementUnits.points});
					}
				}
				//Text frame offset
				with(dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Label Offset:", minWidth:myLabelWidth});
					}
					with(dialogColumns.add()){
						var myLabelOffsetField = measurementEditboxes.add({editValue:0, editUnits:MeasurementUnits.points});
					}
				}
				//Style to apply
				with(dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Label Style:", minWidth:myLabelWidth});
					}
					with(dialogColumns.add()){
						var myLabelStyleDropdown = dropdowns.add({stringList:myStyleNames, selectedIndex:0});
					}
				}
				//Layer
				with(dialogRows.add()){
					with(dialogColumns.add()){
						staticTexts.add({staticLabel:"Layer:", minWidth:myLabelWidth});
					}
					with(dialogColumns.add()){
						var myLayerDropdown = dropdowns.add({stringList:myLayerNames, selectedIndex:0});
					}
				}
			}
		}
        var myResult = myDialog.show(); 
        if(myResult == true){ 
			var myNumberOfRows = myNumberOfRowsField.editValue; 
			var myNumberOfColumns = myNumberOfColumnsField.editValue; 
			var myRemoveEmptyFrames = myRemoveEmptyFramesCheckbox.checkedState;
			var myFitProportional = myFitProportionalCheckbox.checkedState;
			var myFitCenterContent = myFitCenterContentCheckbox.checkedState;
			var myFitFrameToContent = myFitFrameToContentCheckbox.checkedState;
			var myHorizontalOffset = myHorizontalOffsetField.editValue;
			var myVerticalOffset = myVerticalOffsetField.editValue;
			var myMakeLabels = myLabelsGroup.checkedState;
			var myLabelType = myLabelTypeDropdown.selectedIndex;
			var myLabelHeight = myLabelHeightField.editValue;
			var myLabelOffset = myLabelOffsetField.editValue;
			var myLabelStyle = myStyleNames[myLabelStyleDropdown.selectedIndex];
			var myLayerName = myLayerNames[myLayerDropdown.selectedIndex];
			myDialog.destroy();
			myMakeImageCatalog(myFiles, myNumberOfRows, myNumberOfColumns, myRemoveEmptyFrames, myFitProportional, myFitCenterContent, myFitFrameToContent, myHorizontalOffset, myVerticalOffset, myMakeLabels, myLabelType, myLabelHeight, myLabelOffset, myLabelStyle,  myLayerName); 
        } 
		else{
			myDialog.destroy(); 
		}
	}
}
function myGetParagraphStyleNames(myDocument){
	var myStyleNames = new Array;
	var myAddLabelStyle = true;
	for(var myCounter = 0; myCounter < myDocument.paragraphStyles.length; myCounter++){
		myStyleNames.push(myDocument.paragraphStyles.item(myCounter).name);
		if (myDocument.paragraphStyles.item(myCounter).name == "Labels"){
			myAddLabelStyle = false;
		}
	}
	if(myAddLabelStyle == true){
		myStyleNames.push("Labels");
	}
	return myStyleNames;
}
function myMakeImageCatalog(myFiles, myNumberOfRows, myNumberOfColumns, myRemoveEmptyFrames, myFitProportional, myFitCenterContent, myFitFrameToContent, myHorizontalOffset, myVerticalOffset, myMakeLabels, myLabelType, myLabelHeight, myLabelOffset, myLabelStyle,  myLayerName){
	var myPage, myFile, myCounter, myX1, myY1, myX2, myY2, myRectangle, myLabelStyle, myLabelLayer; 
	var myParagraphStyle, myError;
	var myFramesPerPage = myNumberOfRows * myNumberOfColumns;  
	var myDocument = app.documents.add(); 
	myDocument.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points; 
	myDocument.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points; 
	var myDocumentPreferences = myDocument.documentPreferences;  
	var myNumberOfFrames = myFiles.length; 
	var myNumberOfPages = Math.round(myNumberOfFrames / myFramesPerPage); 
	if ((myNumberOfPages * myFramesPerPage) < myNumberOfFrames){  
		myNumberOfPages++; 
	}
	//If myMakeLabels is true, then add the label style and layer if they do not already exist.
	if(myMakeLabels == true){
		try{
			myLabelLayer = myDocument.layers.item(myLayerName);
			//if the layer does not exist, trying to get the layer name will cause an error.
			myLabelLayer.name;
		}
		catch (myError){
			myLabelLayer = myDocument.layers.add({name:myLayerName}); 
		}
		//If the paragraph style does not exist, create it.
		try{
			myParagraphStyle = myDocument.paragraphStyles.item(myLabelStyle);
			myParagraphStyle.name;
		}
		catch(myError){
			myDocument.paragraphStyles.add({name:myLabelStyle});
		}
	}
	myDocumentPreferences.pagesPerDocument = myNumberOfPages;  
	myDocumentPreferences.facingPages = false;  
	var myPage = myDocument.pages.item(0);  
	var myMarginPreferences = myPage.marginPreferences; 
	var myLeftMargin = myMarginPreferences.left;  
	var myTopMargin = myMarginPreferences.top;  
	var myRightMargin = myMarginPreferences.right;  
	var myBottomMargin = myMarginPreferences.bottom;  
	var myLiveWidth = (myDocumentPreferences.pageWidth - (myLeftMargin + myRightMargin)) + myHorizontalOffset
	var myLiveHeight = myDocumentPreferences.pageHeight - (myTopMargin + myBottomMargin)
	var myColumnWidth = myLiveWidth / myNumberOfColumns
	var myFrameWidth = myColumnWidth - myHorizontalOffset
	var myRowHeight = (myLiveHeight / myNumberOfRows)
	var myFrameHeight = myRowHeight - myVerticalOffset
	var myPages = myDocument.pages;
	// Construct the frames in reverse order. Don't laugh--this will  
	// save us time later (when we place the graphics).  
	for (myCounter = myDocument.pages.length-1; myCounter >= 0; myCounter--){  
		myPage = myPages.item(myCounter); 
		for (var myRowCounter = myNumberOfRows; myRowCounter >= 1; myRowCounter--){  
			myY1 = myTopMargin + (myRowHeight * (myRowCounter-1));
			myY2 = myY1 + myFrameHeight;
			for (var myColumnCounter = myNumberOfColumns; myColumnCounter >= 1; myColumnCounter--){  
				myX1 = myLeftMargin + (myColumnWidth * (myColumnCounter-1));
				myX2 = myX1 + myFrameWidth;
				myRectangle = myPage.rectangles.add(myDocument.layers.item(-1), undefined, undefined, {geometricBounds:[myY1, myX1, myY2, myX2], strokeWeight:0, strokeColor:myDocument.swatches.item("None")});  
			} 
		}
	}
	// 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. myFiles = myFolder.Files;  
	for (myCounter = 0; myCounter < myNumberOfFrames; myCounter++){  
		try {
			myFile = myFiles[myCounter];  
			myRectangle = myDocument.rectangles.item(myCounter); 
			myRectangle.place(File(myFile)); 
			myRectangle.label = myFile.fsName.toString();
			//Apply fitting options as specified.
			if(myFitProportional){
				myRectangle.fit(FitOptions.proportionally); 
			}
			if(myFitCenterContent){
				myRectangle.fit(FitOptions.centerContent); 
			}
			if(myFitFrameToContent){
				myRectangle.fit(FitOptions.frameToContent); 
			}
			//Add the label, if necessary.
			if(myMakeLabels == true){ 
				myAddLabel(myRectangle, myLabelType, myLabelHeight, myLabelOffset, myLabelStyle, myLayerName);
			}
		}
		catch(e) {
			alert("Error placing image: " + e);
			continue;
		}
		 
	}
	if (myRemoveEmptyFrames == 1){  
		for (var myCounter = myDocument.rectangles.length-1; myCounter >= 0;myCounter--){  
			if (myDocument.rectangles.item(myCounter).contentType == ContentType.unassigned){ 
				myDocument.rectangles.item(myCounter).remove(); 
			}  
			else{ 
				//As soon as you encounter a rectangle with content, exit the loop. 
				break; 
			} 
		}
	}
}
//Function that adds the label.
function myAddLabel(myFrame, myLabelType, myLabelHeight, myLabelOffset, myLabelStyleName, myLayerName){
	var myDocument = app.documents.item(0);
	var myLabel;
	var myLabelStyle = myDocument.paragraphStyles.item(myLabelStyleName);
	var myLabelLayer = myDocument.layers.item(myLayerName);
	var myLink =myFrame.graphics.item(0).itemLink;
	//Label type defines the text that goes in the label.
	switch(myLabelType){
		//File name
		case 0:
			myLabel = myLink.name;
			break;
		//File path
		case 1:
			myLabel = myLink.filePath;
			break;
		//XMP description
		case 2:
			try{
				myLabel = myLink.linkXmp.description;
				if(myLabel.replace(/^\s*$/gi, "")==""){
					throw myError;
				}
			}
			catch(myError){
				myLabel = "No description available.";
			}
			break;
		//XMP author
		case 3:
			try{
				myLabel = myLink.linkXmp.author
				if(myLabel.replace(/^\s*$/gi, "")==""){
					throw myError;
				}
			}
			catch(myError){
				myLabel = "No author available.";
			}
			break;
	}
	var myX1 = myFrame.geometricBounds[1]; 
	var myY1 = myFrame.geometricBounds[2] + myLabelOffset; 
	var myX2 = myFrame.geometricBounds[3]; 
	var myY2 = myY1 + myLabelHeight;
	var myTextFrame = myFrame.parent.textFrames.add(myLabelLayer, undefined, undefined,{geometricBounds:[myY1, myX1, myY2, myX2], contents:myLabel}); 
	myTextFrame.textFramePreferences.firstBaselineOffset = FirstBaseline.leadingOffset; 
	myTextFrame.parentStory.texts.item(0).appliedParagraphStyle = myLabelStyle;				
}

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 02, 2020 Oct 02, 2020

Copy link to clipboard

Copied

Hi,

Thank you for this script. I am looking to have the images placed at actual size - not fit the boundary box. Please advise on what I need to change in the script to allow for this.

Many thanks,

Lisa

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Oct 02, 2020 Oct 02, 2020

Copy link to clipboard

Copied

LATEST

NM. I figured it out.

Thanks. 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 04, 2020 Aug 04, 2020

Copy link to clipboard

Copied

Are you using the AS or JS version?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines