Home » photoshop » Photoshop scripting with Javascript

Photoshop scripting with Javascript

Mathew Lodge / July 25, 2009 Facebooktwittergoogle_pluspinterestmailFacebooktwittergoogle_pluspinterestmail

I process my images using a combination of Adobe Lightroom and Photoshop, in common with just about every other photographer on the planet. To maximize time spent behind the camera, much of the Photoshop work is automated using Actions, which are a way to record and playback a sequence of Photoshop commands. In other programs such as Microsoft Word or Excel, these are called macros.

Actions are a way of automating Photoshop processes that are performed frequently, but they have one fundamental limitation: there is no way for an action to make a decision by evaluating some condition and doing something different based on the result.

For example, a Photoshop action might downsize an image by 10%. Using the Batch feature of Photoshop, you could apply that action to all images in a folder. However, if you want to downsize only those images in the folder that are larger than, say, 3000 pixels on the longest side, actions and batching can't help you. There's no way for an action to evaluate a condition like "longest side > 3000 pixels". This is where scripting comes in -- you can write a small program (the script), that interacts with Photoshop to perform more complex tasks. Although it might not sound like it, scripting is a form of programming. There is no getting around the fact that you have to learn something about how to write programs to use scripting, and this is its disadvantage compared to Actions.

Photoshop has been "scriptable" since version 7, but scripting support has gotten much better since Photoshop CS2. You can use AppleScript, Microsoft Visual Basic, or Javascript. Some people like to get into language "wars of religion" -- I will say only this: Javascript is the only language that works across PC, Mac or UNIX, and this is a good reason for preferring it, but my primary motivation was efficiency. I chose Javascript because I had learned to program in C and Java. Despite its name, Javascript has very little in common with Java, but both Java and Javascript have very similar syntax to the languages C and C++.

If you are going to do any Photoshop scripting, there are two very helpful PDF documents you need to read. Fortunately, they are installed on your hard drive by the Photoshop installer. The Photoshop Scripting Guide and the Javascript Reference Guide are both in the Photoshop program directory. I won't re-hash those documents, but will provide an example that you can pick apart to figure out how to write your own scripts.

An example script: saving image metadata as XMP files

Some Photoshop commands cannot be recorded as Actions, such as some "File Info" (metadata) changes. Metadata (literally, "data about data") are things like the caption, keywords, title and other information about an image, accessed through the "File Info..." on the File menu. This data is stored as an XML document inside of the image file by Photoshop. The flavor of XML that Photoshop stores is called XMP, and you can save, load and append .xmp files to images using the Advanced panel of the File Info dialog box. The problem is that you can't record saving and loading XMP files in an action. I wanted to use the XMP data in another program to automate keyword display on my web site, so I ended up writing a Javascript program to automate this function.

The code below scans a folder full of JPEG files and outputs the XMP file for any image that has metadata. It is commented, and in conjunction with the documents from Adobe, you ought to be able to understand how the program works, and perhaps adapt it to your own needs. This code is provided free, and purely for its educational value. Enjoy!


// Output xmp.js
// (c) Copyright 2004 Mathew Lodge
// Rev 2, 02-Mar-2004
//
// This script prompts the user for an input directory, which contains JPEG source images.
// It outputs one .xmp metadata file per image, unless the file has no XMP metadata.

// Uncomment the next line to show the debugger
$.level = 1; debugger;

// Save current dialog preferences
var startDisplayDialogs = app.displayDialogs;

// Don't display dialogs
app.displayDialogs = DialogModes.NO;

// Constants
var FILE_TYPE = ".jpg"; // The type of files that this script works on -- you can change
var SEARCH_MASK = "*" + FILE_TYPE; // Image file filter to find only those files
var XMP_TYPE = ".xmp"; // File extension for XMP output files
var MAC_XMP_TYPE = "XMPT"; // Macintosh file type for .xmp files
var MAC_XMP_CREATOR = "8BIM"; // Macintosh file creator for .xmp files

// Set of exception strings for error handling
var X_NOINPUT = "noInput";
var X_BADDOC = "badDoc";
var X_WERROR = "writeError";
var X_CERROR = "closeError";

try {
	// Ask user for input folder
	var inputFolder = Folder.selectDialog("Select a folder to process");
	if (inputFolder == null)
		throw X_NOINPUT;

    // get all files in the input folder
	var fileList = inputFolder.getFiles(SEARCH_MASK);

	// Open each file in turn
	for (var i = 0; i < fileList.length; i++) {
	    // Only want to open non-hidden files (and no folders)
		if ((fileList[i] instanceof File) && (fileList[i].hidden == false)) {
			// Open the file in Photoshop
			var docRef = open(fileList[i]);
			if (docRef == null)
				throw X_BADDOC;

			if (docRef.xmpMetadata != null) {
				// Document has XMP metadata, so process it
				var inFileName = fileList[i].name; // Filename without path
				// Replace the file's current extension (e.g. .jpg) with .xmp
				var outFileName = inFileName.toLowerCase(); // Output file is lower case
				outFileName = outFileName.replace(FILE_TYPE, XMP_TYPE); // Make .xmp
				var outputXMP = new File(inputFolder + "/" + outFileName);
				// Open file for writing. Mac type and creator are ignored on other systems
				var success = outputXMP.open("w", MAC_XMP_TYPE, MAC_XMP_CREATOR);
				if (!success)
					throw X_WERROR;

				// Write out the meta data
				success = outputXMP.writeln(docRef.xmpMetadata.rawData);
				if (!success)
					throw X_WERROR;

				// Close the file
				success = outputXMP.close();
				if (!success)
					throw X_CERROR;
			}
			// Close the Photoshop file
			docRef.close(SaveOptions.DONOTSAVECHANGES);
		}
    }
}
catch (exception) {
	// Show degbug message and then quit
	alert(exception);
}
finally {
	// Reset app preferences
	app.displayDialogs = startDisplayDialogs;
}

Share this: Facebooktwittergoogle_pluspinterestmailFacebooktwittergoogle_pluspinterestmail

3 comments on Photoshop scripting with Javascript

  • I’ve been searching all over for how to us the batch function with a script I had written. Thank you so much for posting this, I was able to figure out exactly what I needed.
     
    Thank you so much!

  • This is a really useful script and I am trying to modify it somewhat. I want to write a script that modifies all of the exposure levels of some raw files in a directory. The problem I have having is that Adobe Camera Raw doesn’t recognise the contents of an XMP file that is written out in this way. Any thoughts?

Leave a Reply