javascript – Photoshop script to export unique layer permutation compositions

I’m using the following script to generate compositions within the top-level document groups. However I want only unique combinations of the layers and not every possible combination.

For example there are 5 elements in 5 colors and I want only unique combinations to be generated, as shown in the screen shot. There should be a total of 120 unique compositions, 24 with a blue background, 24 with a yellow background etc.

The script thats being used is as follows.

var userDisplayDialogsPref = app.displayDialogs;

app.displayDialogs = DialogModes.ALL;

var savePath;

app.displayDialogs = DialogModes.NO;

function getType(thing){
    if(thing === null) return "[object Null]"; // special case
    return Object.prototype.toString.call(thing);
}

function getCombinations(arr, n) {
  if (n == 1) {
      var ret = [];
      for (var i = 0; i < arr.length; i++) {
          for (var j = 0; j < arr[i].length; j++) {
              ret.push([arr[i][j]]);
          }
      }
      return ret;
  } else {
      var ret = [];
      for (var i = 0; i < arr.length; i++) {
          var elem = arr.shift();
          for (var j = 0; j < elem.length; j++) {
              var childperm = getCombinations(arr.slice(), n - 1);
              for (var k = 0; k < childperm.length; k++) {
                  ret.push([elem[j]].concat(childperm[k]));
              }
          }
      }
      return ret;
  }
}

function showAllArtLayers() {
  for(var i = 0; i < layerSets.length; i++) {
    for(var z = 0; z < layerSets[i].artLayers.length; z++) {
      layerSets[i].artLayers[z].visible = true;
    }
  }
}

function hideAllArtLayers() {
  var layerSets = app.activeDocument.layerSets;

  for(var i = 0; i < layerSets.length; i++) {
    if(layerSets[i].artLayers.length) {
      for(var z = 0; z < layerSets[i].artLayers.length; z++) {
        layerSets[i].artLayers[z].visible = false;
      }
    } else {
      for(var z = 0; z < layerSets[i].layerSets.length; z++) {
        layerSets[i].layerSets[z].visible = false;
      }
    }
  }
}

function getArtLayerCollectionCollection() {
  var layerSets = app.activeDocument.layerSets,
      artLayerCollectionCollection = [];

  for(var i = 0; i < layerSets.length; i++) {
    var artlayerCollection = [];
    if(layerSets[i].artLayers.length) {
      for(var z = 0; z < layerSets[i].artLayers.length; z++) {
        if(layerSets[i].name.indexOf('__') !== 0)
          artlayerCollection.push(layerSets[i].artLayers[z]);
      }
    } else {
      for(var z = 0; z < layerSets[i].layerSets.length; z++) {
        if(layerSets[i].name.indexOf('__') !== 0)
          artlayerCollection.push(layerSets[i].layerSets[z]);
      }
    }
    artLayerCollectionCollection.push(artlayerCollection);
  }

  return artLayerCollectionCollection;
}

function combine() {
  var artLayerCollectionCollection = getArtLayerCollectionCollection(),
      artLayerCollectionCollectionCombinations = getCombinations(artLayerCollectionCollection, getLayerSetsCount()),
      continueConfirmation;

      if(! artLayerCollectionCollectionCombinations.length) return alert('Script has aborted. No combinations found. Please make sure no empty groups are present.');

      continueConfirmation = confirm(artLayerCollectionCollectionCombinations.length + " combinations found. Would you like to continue?");

      if(! continueConfirmation ) return alert('Script has been aborted.');

      savePath = Folder.selectDialog("Select an output folder");

      var includePSDFiles = confirm('Would you like to include corresponding PSD documents?')

      for(var i = 0; i < artLayerCollectionCollectionCombinations.length; i++) {
        hideAllArtLayers();
        var artLayerNames = [];
        for(var z = 0; z < artLayerCollectionCollectionCombinations[i].length; z++) {
          var artLayer = artLayerCollectionCollectionCombinations[i][z];
          artLayer.visible = true;
          artLayerNames.push(artLayer.parent.name);
          artLayerNames.push(artLayer.name);
        }
        saveDocumentAsPNG(savePath + "https://stackoverflow.com/" + normalizeSaveFileName(artLayerNames.join('')).substr(0, 254));
        if(includePSDFiles) saveDocumentAsPSD(savePath + "https://stackoverflow.com/" + normalizeSaveFileName(artLayer.parent.name + artLayerNames.join('')).substr(0, 254));
      }
}

function getSmallestLayerSetCount() {
  var count = null,
  layerSets = app.activeDocument.layerSets;

  for(var i = 0; i < layerSets.length; i++) {
    var artLayers = layerSets[i].artLayers;

    if(count === null) count =  artLayers.length;

    if(artLayers.length < count) count = artLayers.length;
  }

  return 1;
}

function getLayerSetsCount() {
  var layerSets = app.activeDocument.layerSets,
      count = 0;

  for(var i = 0; i < layerSets.length; i++) {
    if(layerSets[i].name.indexOf('__') !== 0) count++;
  }

  return count;
}

function normalizeSaveFileName(name) {
  return name;
}

function saveDocumentAsPNG(path) {
  app.activeDocument.saveAs(new File(path), new PNGSaveOptions());
}

function saveDocumentAsPSD(path) {
  app.activeDocument.saveAs(new File(path), new PhotoshopSaveOptions());
}

combine();

app.displayDialogs = userDisplayDialogsPref;

The logic would have to be for example: if the background is “blue” then don’t use any layer named blue in the other group layers AND not to use the same color in other group layers, all the layers in all the groups have the color prefixed, as in “blue hills” or “red sun”.

I’m not sure how to go about modifying the above script to achieve the intended result.


In Photoshop the PSD has the following grouping for example.

-Hills (Group)

–Red hills

–Blue hills

–Yellow hills

-Sun (Group)

–Red sun

–Blue sun

–Yellow sun

-Background (Group)

–Red background

–Blue background

–Yellow background

So if the “–Red background” layer from the group “Background” is used then “–Red sun” from the group “”Sun” and “–Red hills” from the group “Hills” cannot be used.

AND

Same colors cannot be used in the other groups, example,

If background layer used is blue and hills are red then sun cannot be red.

Leave a Comment