C#

Automating PhotoShop Tasks Using PhotoShop APIs.

by WeblashAdmin on Sep.27, 2009, under C#, development

Melchor Berona of Photo-Essence recently hired me to design his website. One of his feature requests was to enable a fast, easy way to get photos to his galleries online. This sounds simple enough, I thought, and off I went.

As for any business, Melchor didn’t want to spend valuable hours replacing images in his online photo galleries. He wanted to get the high resolution photos to a usable format and size; then FTP to his site. The process turned out to be this:

  1. Get images to 96ppi
  2. Convert images to RGB
  3. Resize landscape or portrait to 600px height
  4. Save file with the correct filename to be used in the destination galleries – old files would be swapped with new files, so the naming on the new images needed to be the same as the images being replaced
  5. Create thumbnail images that are 150x150px
  6. save file with the appropriate naming
  7. FTP the new files (not covered here)

So I thought: I’ll just create a droplet – no problem, right? Well, it’s not ideal when you’re resizing both landscape and portraits using the scaling in PhotoShop. This really can’t be automated unless you make two separate droplets, one for landscape and one for portrait.

Then I discovered a folder in the PhotoShop directories (in the Programs directory) that gives a pretty good introduction to automating tasks (and more) using scripting in JavaScript, VBScript, or ActionScript.

OK – now we’re getting somewhere, I thought. However, I wanted to take this a step further. I wanted to make a C# console application using the PhotoShop APIs. I didn’t find much documentation, but I did find a very good tutorial  by John Deurbrouck here: http://www.pcpix.com/Photoshop/.

After I read that I was on my way. For this blog entry, I’d like to walk through my process of developing the application I delivered to my client.

Step 1 – Do Some Research

Get information on PhotoShop Scripting here: http://www.adobe.com/devnet/photoshop/scripting/

There are some PDFs here that go into detail about scripting for VB, JavaScript, and AppleScript. There’s also information about the ScriptListener.

Step 2 – turn on the ScriptListener

The PhotoShop ScriptListener logs every event you do in PhotoShop, from opening a document, modifications, saving, and closing it. So it should only be turned on when you are performing the steps you’ll use for your automation application. From Adobe…

Installing ScriptListener

The ScriptListener plug-in is located in the ..\Adobe Photoshop CS4\Scripting\Utilities folder.

To install the ScriptListener:

  1. Select the file ScriptListener.8li and then choose Edit > Copy.
  2. Paste the file copy to the following location: ..\Adobe Photoshop CS4\Plug-Ins\Automate
  3. Open Photoshop.
    1. NOTE: If Photoshop is already open, close it and then start it again. This will allow Photoshop to load
      the plug-in.

To uninstall the ScriptListener:

  1. Close Photoshop.
  2. Verify that a copy of the file ScriptListener.8li still exists in the ..\Adobe Photoshop CS4\
    Scripting\Utilities folder.
  3. Delete the file ScriptListener.8li from the following location: ..\Adobe Photoshop CS\Plug-Ins\Automate
  4. Delete the log files ScriptingListenerJS.log and ScriptingListenerVB.log from your desktop.
    1. NOTE: In Windows, even though you remove the ScriptListener from the Automate folder, it may continue
      to record actions. To prevent the ScriptingListenerJS.log file from becoming too large, delete it each
      time you finish playing a Photoshop action.

So when you’re ready to simulate an automation, go to your Actions, create a new action, and start going through the steps. When you’re finished, you’ll see two files on your desktop:

ScriptingListenerJS.log, containing JavaScript code
ScriptingListenerVB.log, containing VBScript code

These files contain – you guessed it, the steps you just performed when you created the action.

Now you can see the code that defined the steps in the action. From here you can convert these steps to C# with some help from the documentation by John Deurbrouck here: http://www.pcpix.com/Photoshop/.

Step 3 – Write your functions

I created a separate class in my application that contains all the PhotoShop action steps (opening the file, resizing, saving, changing canvas size, etc.). Below is an example:

public static void Resize(int iHeight, string category)
        {
            //get the original document dimensions
            double dWidth = getdim("X");
            double dHeight = getdim("Y");
            //convert datatype of iHeight
            double dNewHeight = Convert.ToDouble(iHeight);

            switch (category)
            {
                case "full":
                    break;
                case "mid":
                    //is the document landscape or portrait?
                    if (dWidth < dHeight)
                    {
                        //is portrait
                        dNewHeight = 300;
                    }
                    else
                    {
                        dNewHeight = 200;
                    }
                    break;
                case "thumb":
                    //is the document landscape or portrait?
                    if (dWidth < dHeight)
                    {
                        //is portrait
                        dNewHeight = (dHeight * dNewHeight) / dWidth;
                    }
                    break;
            }
            //run the action
            //describe the action
            int idImgS = app.CharIDToTypeID("ImgS");
            ps.ActionDescriptor desc3 = new ps.ActionDescriptor();
            //image height
            int idHght = app.CharIDToTypeID("Hght");
            //image resolution
            int idPxl = app.CharIDToTypeID("#Pxl");
            //not sure what the below does
            desc3.PutUnitDouble(idHght, idPxl, dNewHeight);
            //scale the styles too?
            int idscaleStyles = app.StringIDToTypeID("scaleStyles");
            desc3.PutBoolean(idscaleStyles, true);
            //the canvas?
            int idCnsP = app.CharIDToTypeID("CnsP");
            desc3.PutBoolean(idCnsP, true);
            //not sure what these do
            int idIntr = app.CharIDToTypeID("Intr");
            int idIntp = app.CharIDToTypeID("Intp");
            int idBcbc = app.CharIDToTypeID("Bcbc");
            //add the properties to prep execution
            desc3.PutEnumerated(idIntr, idIntp, idBcbc);
            //run execution of action
            app.ExecuteAction(idImgS, desc3, ps.PsDialogModes.psDisplayNoDialogs);
        }

So I have to admit it’s been quite a while since I wrote the code, and I am sketchy about defining the actions. http://www.pcpix.com/Photoshop/ has all the details about just what the code is that defines the action, and lists all of the enum names and values. I have asked John Deurbrouck and pcpix.com if I can distribute the article as a Word doc from my blog. I’ll keep you updated.

If you take on a project like this, you’ll find you’ll need to do some conversions from the code in the ScriptListener file to the C# code for the actions to get prepped properly.

Anyhow, this is a start. Please send me feedback! I’m not an experienced blogger so comments would be helpful.

4 Comments :, , , , more...