Photoshop 脚本:重新链接智能对象

Photoshop Scripting: Relink Smart Object

我正在编写一个脚本,它应该通过一个 photoshop 文档并将所有可见的链接对象重新链接到一个新的指定文件。我已经使循环正常工作,因此它循环遍历每一层并仅收集可见层,但对于我的一生,我找不到是否有可用于重新链接智能对象的方法。我找到的最接近的是这个脚本:

https://gist.github.com/laryn/0a1f6bf0dab5b713395a835f9bfa805c

但是当它到达 desc3.putPath(idnull, new File(newFile)); 时,它会吐出一个错误,指出当前的 Photoshop 版本中可能不存在该功能。该脚本本身已有 4 年历史,因此可能已过时。

如有任何帮助,我们将不胜感激!

我的 脚本如下:

// SELECT FILE //

var files = File.openDialog("Please select new linked file");

var selectedFile = files[0];

// GET ALL LAYERS //

var doc = app.activeDocument;
var allLayers = [];
var allLayers = collectAllLayers(doc, allLayers);

function collectAllLayers (doc, allLayers)
{
    for (var m = 0; m < doc.layers.length; m++)
    {
        var theLayer = doc.layers[m];
        
        if (theLayer.typename === "ArtLayer")
        {
            allLayers.push(theLayer);
        }
        else
        {
            collectAllLayers(theLayer, allLayers);
        }
    }
    return allLayers;
}

// GET VISIBLE LAYERS //

var visibleLayers = [];

for (i = 0; i < allLayers.length; i++)
{
    var layer = allLayers[i];
    
    if (layer.visible && layer.kind == LayerKind.SMARTOBJECT)
    {
        visibleLayers.push(layer);
    }
}

// REPLACE LAYERS

for (i = 0; i < visibleLayers.length; i++)
{
    var layer = visibleLayers[i];
    
    //--> REPLACE THE FILE HERE 
}

注意:我知道如果您不确切了解该脚本的工作原理,该脚本目前可能容易出错;我不打算在这个时候发布它,所以我现在不是很关心这个。大多数情况下,我只需要核心功能即可工作。

我使用了一个 AM 函数来获取可见的智能对象——它工作得更快。但如果你愿意,你可以使用你的。重要的一点是 relinkSO(path);:它也可以在您的脚本中使用(只是不要忘记 select 一层:activeDocument.activeLayer = visibleLayers[i];

请注意,它的工作原理类似于 Photoshop Relink to File 命令 - 如果在智能对象的一个​​实例上使用,所有实例都将被重新链接。如果你只想重新链接特定层,你必须先中断实例化(可能使用 New Smart Object via Copy 命令)

function main() {
  var myFile = Folder.myDocuments.openDlg('Load file', undefined, false);
  if (myFile == null) return false;
  
  // gets IDs of all smart objects
  var lyrs = getLyrs();

  for (var i = 0; i < lyrs.length; i++) {
    // for each SO id...

    // select it
    selectById(lyrs[i]);

    // relink SO to file
    relinkSO(myFile);

    // embed linked if you want
    embedLinked()
  }

  function getLyrs() {
        var ids = [];
        var layers, desc, vis, type, id;

        try
        {
          activeDocument.backgroundLayer;
          layers = 0;
        }
        catch (e)
        {
          layers = 1;
        }

        while (true)
        {
          ref = new ActionReference();
          ref.putIndex(charIDToTypeID('Lyr '), layers);
          try
          {
            desc = executeActionGet(ref);
          }
          catch (err)
          {
            break;
          }
          vis = desc.getBoolean(charIDToTypeID("Vsbl"));
          type = desc.getInteger(stringIDToTypeID("layerKind"));
          id = desc.getInteger(stringIDToTypeID("layerID"));
          if (type == 5 && vis) ids.push(id);
          layers++;
        }
        return ids;

  } // end of getLyrs()

  function selectById(id) {
        var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID('Lyr '), id);
        desc.putReference(charIDToTypeID('null'), ref);
        executeAction(charIDToTypeID('slct'), desc, DialogModes.NO);
  } // end of selectById()
  
  function relinkSO(path) {
      var desc = new ActionDescriptor();
      desc.putPath( charIDToTypeID('null'), new File( path ) );
      executeAction( stringIDToTypeID('placedLayerRelinkToFile'), desc, DialogModes.NO );
  } // end of relinkSO()

  function embedLinked() {
      executeAction( stringIDToTypeID('placedLayerConvertToEmbedded'), undefined, DialogModes.NO );
  } // end of embedLinked()
  
}
app.activeDocument.suspendHistory("relink SOs", "main()");