Friday, February 10, 2012

JavaScript for Photoshop - When Macros Aren't Enough

This2That Tile Sample

A few years ago, a fellow named Brian Dorn got in touch with me. He was working on his doctoral dissertation at Georgia Tech and he needed participants. I met him in Atlanta and found out that his study was about scripting with Photoshop. That was the first I'd ever heard of Adobe Photoshop Scripting.

A few weeks ago when I started working on a new word game This2That for Mobile Magic Developers, I needed to generate 38 tiles with letters, numbers, and punctuation. The task was tedious and the macros just couldn't make it any easier. Then I realized I had the embossing all wrong and I had to start over!

Frustrated, I tried to think of a better way. I remembered Brian Dorn and I started looking into this Adobe Photoshop JavaScript thing. I was very pleased when 15 minutes of script became an easily reusable tile generating utility. Now, I can take any PSD, open it up, select any text layer, and have the script generate a PNG for each letter I need

I thought this little known feature would make for interesting reading for both programmers and designers so here's my script:

// call the method that does all of the work
main();

// wrap the code in a method to make it easier to debug
function main() {

 // make sure you're working in a document and have a text layer selected
 if (!activeDocument || !activeDocument.activeLayer || activeDocument.activeLayer.kind != LayerKind.TEXT)
 {
   alert("Please select a document and a target text layer.");
   return;
 }
 
 // set up some information about the current file
 var textLayer = activeDocument.activeLayer;
 var path = activeDocument.path;
 var fileName = activeDocument.name;
 
 // remove the extension on the file name
 var extensionPosition;
 if (extensionPosition = fileName.lastIndexOf('.'))
  fileName = fileName.substr(0, extensionPosition);

 // get a good place to put the file
 var outputFolder = Folder.selectDialog("Select a target folder.", path);
 
 // set up the letters we want images for
 var characterMap = [
  ["question", "?"]
 ];
 
 // and add the lowercase alphabet and numbers
 characterMap = characterMap.concat(getAsciiRange(97, 26), getAsciiRange(48, 10));

 // for each character, update the selected text layer and save a file
 for (var i = 0; i < characterMap.length; i++)
 {
   var character = characterMap[i][1];
   var fileSuffix = characterMap[i][0];
   
   textLayer.textItem.contents = character;
   
   var file = new File(outputFolder + "/" + fileName + "_" + fileSuffix + ".png");
   var options = new PNGSaveOptions();
   options.interlaced = false;

   activeDocument.saveAs(file, options, true, Extension.LOWERCASE);
 }
};

// a little helper method to make a range of letters and their
// filename extensions
function getAsciiRange(from, count) {
 var result = [];

 for (var i = 0; i < count; i++)
 {
  var character = String.fromCharCode(i + from);
  result.push([character, character.toUpperCase()]);
 } 
 
 return result;
}
 

No comments:

Post a Comment