Photoshop 重命名脚本不会遍历文件夹中的图层

Photoshop renaming script does not iterate through layers within folders

除了一个方面之外,该脚本工作完美:它不会遍历嵌套在文件夹中的层。我尝试根据 this 问题将 layers 更改为 layerSets,但随后它停止处理文件夹名称。我在 Mac Catalina 上使用 Photoshop 2020。

// JavaScript Document
var doc = app.activeDocument;

// name indexed object
var layernames = {
 'Products':'Working',
 'Product':'Working',
 'Notes':'Note',
 'Background color':'Background Colour',
 'White background':'White Background'
};

// loop through all layers
for (var i = 0; i < doc.layers.length; i++)
{

 //Set up Variable to access layer name
 var currentLayer = app.activeDocument.layers;

 if (layernames[currentLayer.name]) {
     currentLayer.name = layernames[currentLayer.name];
 }
}

据我从文档 (https://www.adobe.com/content/dam/acom/en/devnet/photoshop/pdfs/photoshop-scripting-guide-2020.pdf) 中了解到,图层可能包含 ArtLayers 或 LayerSets。 LayerSets 包含其他嵌套图层...

您可以创建一个函数来重命名每个层(您所做的),但是当它遇到 LayerSet 时,也递归地调用 currentLayer.layers 上的函数。

要了解特定图层是否为 LayerSet,请尝试 if (currentLayer.layers) ...

考虑以下解决方案,它利用名为 renameLayersrecursive function 遍历文档层树结构中的所有层节点。

typename 属性 可以设置为 ArtLayerLayerSet。本质上,当层 typenameLayerSet(即文件夹)时,我们再次递归调用该函数。


var doc = app.activeDocument;

/**
  * Rename layers in a Photoshop document.
  *
  * @param {Object} doc A reference to the document to change.
  * @param {Object} layerName Each property key name indicates the original layer
  * name, and its corresponding value indicates the new layer name.
  * @param {Object} options The configuration options.
  * @param {Boolean} [options.includeTextLayers=false] Whether to rename text layers.
  * @param {Boolean} [options.includeLayerSets=false] Whether to rename LayerSets.
  */
function renameLayers(doc, layerNames, options) {

  // Default options
  var opts = {
    includeTextLayers: false,
    includeLayerSets: false
  };

  // Overwrite properties in the default `opts` object by properties in the
  // user defined `options` object if they have the same key. Shallow copy only.
  if (typeof options === 'object') {
    for (var key in opts) {
      if (options.hasOwnProperty(key)) {
        opts[key] = options[key];
      }
    }
  }

  // Iterate each layer in the document.
  for (var i = 0, max = doc.layers.length; i < max; i++) {
    var currentLayer = doc.layers[i];

    if (currentLayer.typename === 'ArtLayer') {

      if (layerNames[currentLayer.name]
          && (opts.includeTextLayers || currentLayer.kind !== LayerKind.TEXT)) {
        currentLayer.name = layerNames[currentLayer.name];
      }

    } else { // The layers `typename` is a `LayerSet`

      if (layerNames[currentLayer.name] && opts.includeLayerSets) {
        currentLayer.name = layerNames[currentLayer.name];
      }
      renameLayers(currentLayer, layerNames, options); // Resursive call
    }
  }
}


// Demo Usage

var layerNames = {
  'Products': 'Working',
  'Product': 'Working',
  'Notes': 'Note',
  'Background color': 'Background Colour',
  'White background': 'White Background'
};

renameLayers(doc, layerNames);

使用说明:

正如您在最后一行代码(上面)中看到的,我们按如下方式调用 renameLayers 函数:

renameLayers(doc, layerNames);

这里我们传入 doc 变量,即对要更改的文档的引用,以及定义原始图层名称和新图层名称映射的 layerNames 对象。

运行 上面显示的代码(按原样)将根据 layerNames 对象中指定的映射重命名任何层。但是,它目前不会重命名任何文本图层或图层集。

如何重命名文本图层 and/or LayerSets?

renameLayers 函数列出了第三个可选参数,名为 options 以允许定义自定义配置。

以下三个函数调用演示了如何通过传入可选的 options 参数来实现不同的配置:

  • includeLayerSets 设置为 true 调用如下函数也会重命名图层集:

    renameLayers(doc, layerNames, { includeLayerSets: true });
    
  • includeTextLayers 设置为 true 调用如下函数也会重命名文本层:

    renameLayers(doc, layerNames, { includeTextLayers: true });
    
  • includeLayerSetsincludeTextLayers 设置为 true 来调用如下函数也会重命名图层集和文本图层:

    renameLayers(doc, layerNames, {
      includeLayerSets: true,
      includeTextLayers: true
    });