whatspop - Kunal Anand

Ever wanted to script Photoshop?

1/15/2007

I have been allocating a lot of time from researching and reading to help my parent's create a dynamic web site for their family business. Part of the job entails transforming every page from a 77 megabyte PDF catalog into a web ready JPG.
From a quick brainstorming session, while checking email no less, I came up with four different ways of doing image resizing:

  • Invoke a Photoshop COM object through PowerShell (which seriously rocks) or C#. The only snag is that I would have to get an SDK or find out what exactly to call - which can sometimes be like looking for a needle in a haystack. Sadly a Google search for Photoshop and COM did not turn up anything tasty to chew on.
  • Use JavaScript within Photoshop. Interestingly, Adobe has a great amount of information for scripting Photoshop through AppleScript, JavaScript, and VBScript.
  • Whip up some Python, invoking PIL and some PDF package. This seems pretty attractive, as I get to spend time in my favorite language. Although, I really don't want to muck with some extraneous thing to handle PDFs.
  • Do it manually. This is incredibly unreasonable, since I only have a modicum of time to spend on the project.
So I ended up going with option two, which was surprisingly awesome. Here is the source code from the whole thing (which is really easy to follow). I start the script by initializing the necessary variables:

total_pages = 68;
full_document_path = "~/Project/Assets/catalog.pdf";
full_output_path = "~/Project/Assets/jpg/";

I set the page count (which I could have probably read from Photoshop too now that I think about it), and the document paths. Now we go on to create a function that handles opening a particular page of a PDF:

function open_document(page) {
FileReference = new File(full_document_path);
PDFOpenOptions = new PDFOpenOptions();
PDFOpenOptions.page = page;
PDFOpenOptions.resolution = 72;
app.open(FileReference, PDFOpenOptions);
}

Photoshop cannot open all the pages of a PDF file, so we have to manually determine what page we want to resize (in my case, just opening each page at a particular resolution is perfect). With that, we set the resolution to 72 (the original resolution of the document is 600). Now let's get to the next function, which involves saving the document:

function save_document(page) {
jpgFile = new File(full_output_path + page + ".jpeg");
jpgSaveOptions = new JPEGSaveOptions();
jpgSaveOptions.embedColorProfile = true;
jpgSaveOptions.quality = 12;
app.activeDocument.saveAs(jpgFile, jpgSaveOptions, true, Extension.LOWERCASE);
}

Since my parents' products have a lot of detail, I set the JPG quality to the highest, which is 12. Again, this is pretty straight-forward. Now, let's go ahead and write our one-line function that closes the active document:

function close_document() {
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}

I did not really need to make a function around this, I just thought it was more convenient to call close_document than that whole string every time. Got this far? Well, you have all the libraries for the app put together. Now, let's write the logic:

for (i=1; i<=total_pages; i++) {
open_document(i);
save_document(i);
close_document();
}

Tada! That iterates over the variable we initialized at the top of the script and we are in business. Throw this file into your /Photoshop/Presets/Scripts/ directory, open Photoshop, goto File > Scripts, select the script and enjoy watching JavaScript do all the work for you.

I am still figuring out the kinks in the Photoshop object model, but this route was definitely a time saver. I would reccomend other efficiency junkies give this a shot.

About I am currently a Senior Engineer at MySpace. Feel free to check out my personal collective.

Archives
April 2005
May 2005
June 2005
July 2005
August 2005
September 2005
October 2005
November 2005
December 2005
January 2006
March 2006
April 2006
May 2006
June 2006
July 2006
August 2006
September 2006
October 2006
November 2006
January 2007
February 2007
April 2007
November 2007
December 2007
January 2008
March 2008
April 2008
May 2008
June 2008

Subscribe to my feed