bipo
bipo

Reputation: 31

Photoshop scripting: export layers combinations in separate files

In a Photoshop CS5 I have two groups of layers: "MODEL" and "MATERIAL."

While the first one ("MODEL") will contain simple layers ("Model Tom", "Model Jim", "Model Harry"...), the other one ("MATERIAL") will contain another group instead: "METAL", "WOOD" etc. OF course these groups of materials will have other layers themselves ("METAL" will contain: "Iron", "steel", "Copper" etc, "WOOD" will contain "Oak", "Cherry", "Maple" and so on).

What I would like to do is to export a jpg file (quality 72) formed by the combination of each MODEL with all the MATERIALS. Two layers merged in one file.

The file name must be the same of the last sub-MATERIAL layer that is going to be exported, and the destination folder (which should possibly be created at the moment) should be called as the MODEL instead.

Following the example above, you would have something like:

MODEL TOM
-Iron.jpg
-Steel.jpg
-Copper.jpg
-Oak.jpg
-Cherry.jpg
-Maple.jpg

MODEL JIM
-Iron.jpg
-Steel.jpg
-Copper.jpg
-Oak.jpg
-Cherry.jpg
-Maple.jpg

MODEL HARRY
-Iron.jpg
-Steel.jpg
-Copper.jpg
-Oak.jpg
-Cherry.jpg
-Maple.jpg

I know a little of php and javascript. It is very complicated to make something like that? Have you any suggestion? thanks!

Upvotes: 0

Views: 452

Answers (1)

Ghoul Fool
Ghoul Fool

Reputation: 6949

Welcome to Photoshop scripting. Looping over layers is easy, but it gets complicated with groups (and can be a bit of a headache) and there's no easy way of indexing things.

This script will do you want you want (based on a script that did a similar thing for a more complicated set up) It'll loop over all the layers and fill two arrays one with everything in the Avatar group, the other with everything in the background group.

Put Tom, Jim & Harry layers in a group called "avatars" and everything else in a group called "backgrounds". When run, the script will save out the files into a folder called "output".

//pref pixels
app.preferences.rulerUnits = Units.PIXELS;

// call the source document
var srcDoc = app.activeDocument;

// vegetables
var numOfLayers = srcDoc.layers.length;
var layers = srcDoc.layers;

// group layer vegetables
var charArr  = new Array();  // Tom, Jim & Harry avatars
var bkgArr  = new Array(); // background images

var allLayers = new Array();
var theLayers = collectAllLayers(app.activeDocument, 0);

// go over the character image layers
getLayerNamesInGroupsFromArray(charArr);

// go over the background image layers
getLayerNamesInGroupsFromArray(bkgArr);

// Characters on backgrounds
loopOverGroup("backgrounds", bkgArr, "avatars", charArr);

function loopOverGroup(groupname1, arr1, groupname2, arr2)
{

  for (var i = 0; i < arr1.length; i++)
  {
    var subLayer1 = arr1[i];

    app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName(groupname1).artLayers.getByName(subLayer1);
    app.activeDocument.activeLayer.visible = true;

    for (var j = 0; j < arr2.length; j++)
    {
      var subLayer2 = arr2[j];
      // alert(subLayer2);

      app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName(groupname2).artLayers.getByName(subLayer2);
      app.activeDocument.activeLayer.visible = true;

      // Name the file
      var tempName = subLayer1 + "_" + subLayer2;

      duplicateIt(tempName);
      activeDocument.flatten();

      //create folder for it
      makeDirectory("output", srcDoc.path);

      // Set filePath and fileName to source path
      var filePath = srcDoc.path + "/output/" + tempName + ".jpg";

       myJpgQuality = 12;

      // jpg file options
      var jpgFile = new File(filePath);
      jpgSaveOptions = new JPEGSaveOptions();
      jpgSaveOptions.formatOptions = FormatOptions.OPTIMIZEDBASELINE;
      jpgSaveOptions.embedColorProfile = true;
      jpgSaveOptions.matte = MatteType.NONE;
      jpgSaveOptions.quality = myJpgQuality;

      activeDocument.saveAs(jpgFile, jpgSaveOptions, true, Extension.LOWERCASE);

      // close it
      app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
      app.activeDocument = srcDoc;

      app.activeDocument.activeLayer.visible = false;
    } // end loop j
  }// end loop i

}



// function collect all layers
function collectAllLayers (theParent, level)
{
  for (var m = theParent.layers.length - 1; m >= 0; m--)
  {
    var theLayer = theParent.layers[m];
    var parentName = "Background";

    if (theParent.typename == "LayerSet")
    {
      if (level == 1) parentName = theParent.name;
    }

    // apply the function to layersets;
    if (theLayer.typename == "ArtLayer")
    {

      // switch the background background layer on
      var layerName = theLayer.name;
      if (parentName != "Background")
      {
        theLayer.visible = true;
      }

      // looking for backgrounds
      if (parentName == "backgrounds")
      {
        bkgArr.push (parentName + ":" + theLayer.name);
        theLayer.visible = false;
      }

      // looking for avatars
      if (parentName == "avatars")
      {
        charArr.push (parentName + ":" + theLayer.name);
        theLayer.visible = false;
      }
    }
    else
    {
      allLayers.push(level + theLayer.name);
      collectAllLayers(theLayer, level + 1)
    }
  }
}


function duplicateIt(str)
{
  // duplicate image into new document
  if (arguments.length == 0) str = "temp";

  var id428 = charIDToTypeID( "Dplc" );
  var desc92 = new ActionDescriptor();
  var id429 = charIDToTypeID( "null" );
  var ref27 = new ActionReference();
  var id430 = charIDToTypeID( "Dcmn" );
  var id431 = charIDToTypeID( "Ordn" );
  var id432 = charIDToTypeID( "Frst" );
  ref27.putEnumerated( id430, id431, id432 );
  desc92.putReference( id429, ref27 );
  var id433 = charIDToTypeID( "Nm  " );
  desc92.putString( id433, str ); // name
  executeAction( id428, desc92, DialogModes.NO );
}



function getLayerNamesInGroupsFromArray(arr)
{
  // go over the background image layers
  for (var i = 0; i < arr.length; i++)
  {
    var temp = arr[i].toString();

    var groupName = temp.substring(0, temp.indexOf(":"));
    var layerName = temp.substring(temp.indexOf(":")+1, temp.length);
    arr[i] = layerName;
  }
  return arr;
}

function makeDirectory(foldername, apath)
{
  // create directory
  var myDirectoryName = apath + "/" + foldername;
  var myDirectory = new Folder(myDirectoryName);
  if(!myDirectory.exists) myDirectory.create();
}

Upvotes: 0

Related Questions