Photoshop脚本 - 当前图层下方的新图层

时间:2014-10-10 08:52:47

标签: photoshop photoshop-script

我是Photoshop初学者,目前使用的是Photoshop CS3版本。我一直使用键盘快捷键来加速设计过程,例如创建新图层等。

但是,我觉得Photoshop必须具备的一个命令是在当前工作层下面创建一个新图层,因此我无法通过快捷方式分配它。

我必须在当前图层上方创建一个新图层,然后手动将其拖动到当前图层下方,我觉得可以使用操作或脚本进行自动化,这对我来说都很难成为初学者。

在这方面,有人可以帮助我。

由于 DKJ

3 个答案:

答案 0 :(得分:1)

可以使用以下内容编写脚本:

// Create a new layer below current active layer
// And call it "The Layer Below"
createLayerBelowCurrent("The Layer Below");


function createLayerBelowCurrent(astring)
{
  var currentActivelayer = app.activeDocument.activeLayer;
  var idx = getLayerIndex(currentActivelayer);

  // Get a reference to the active layer
  var layerRef = app.activeDocument.layers[idx];

  // Create a new Art Layer, by default at the top of the document
  var newLayerRef = app.activeDocument.artLayers.add();

  // Move the new layer set to after the previously first layer
  newLayerRef.move(layerRef, ElementPlacement.PLACEAFTER);
}


function getLayerIndex(ref)
{
  // return the idex of ALL layers
  var numOfLayers = app.activeDocument.layers.length;

  // work from the top of the stack down!
  for (var i = numOfLayers -1; i >= 0; i--)
  {
    var tempLayer = app.activeDocument.layers[i];
    if (tempLayer == ref) return i

    if (tempLayer.typename == "LayerSet")
    {
      var subDoc = app.activeDocument.layers[i];
      for (var j = numOfSubLayers -1; j >= 0; j--)
      {
        var tempSubLayer = subDoc.layers[j]
        if (tempSubLayer == ref) return j
      }
    }
  }
}

然后,您可以将此脚本录制为动作,并将其放在键盘快捷方式上。

答案 1 :(得分:0)

几年前,我认为使用DOM的原生PS API很酷,应该更快,但实际上它的callstack通常甚至比通过动作执行的相同命令更大。 +有时DOM函数由多个底层调用组成,例如artLayers.add(),实际上是make layer +将它移动到文档的顶部。所以这是我的PS脚本库中该功能的动作版本:

// get current layer number
function curLyrN(){
    if(app.activeDocument.artLayers.length<2) return 1;
    var idLyr = charIDToTypeID("Lyr ");
    var idItmI = charIDToTypeID("ItmI");
    var aref = new ActionReference(); 
    aref.putEnumerated(idLyr, charIDToTypeID("Ordn"), charIDToTypeID("Trgt")); 
    var id = executeActionGet(aref).getInteger(charIDToTypeID("LyrI"));
    aref = new ActionReference(); 
    aref.putProperty(charIDToTypeID("Prpr"), idItmI); 
    aref.putIdentifier(idLyr, id); 
    id = executeActionGet(aref).getInteger(idItmI);
    if(id) return id;
    return 0; 
}

// select [LayerNum], optionally [add] to selection (if add=2: with inclusion)
function selLyr(LyrN,add){
    var adesc = new ActionDescriptor();
    var aref = new ActionReference();
    aref.putIndex(charIDToTypeID("Lyr "), LyrN);
    adesc.putReference(charIDToTypeID("null"), aref);
    if(add){
        add = (add==2) ? stringIDToTypeID("addToSelectionContinuous") : stringIDToTypeID("addToSelection");
        adesc.putEnumerated(stringIDToTypeID("selectionModifier"),stringIDToTypeID("selectionModifierType"),add);
    }
    adesc.putBoolean(charIDToTypeID("MkVs"), false);
    return executeAction(charIDToTypeID("slct"), adesc, DialogModes.NO);
}

// move current layer to [LayerNum]
function movLyr(LyrN){
    var idLyr = charIDToTypeID("Lyr ");
    var adesc = new ActionDescriptor();
    var aref = new ActionReference();
    aref.putEnumerated(idLyr, charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    adesc.putReference(charIDToTypeID("null"), aref);
    aref = new ActionReference();
    aref.putIndex(idLyr, LyrN);
    adesc.putReference(charIDToTypeID("T   "), aref);
    adesc.putBoolean(charIDToTypeID("Adjs"), false);
    return executeAction(charIDToTypeID("move"), adesc, DialogModes.NO);
}

// create new empty layer
function mkLyr(){
    var aref = new ActionReference();
    aref.putClass(charIDToTypeID("Lyr "));
    var adesc = new ActionDescriptor();
    adesc.putReference(charIDToTypeID("null"), aref);
    return executeAction(charIDToTypeID("Mk  "), adesc, DialogModes.NO);
}

// count all inner layers from layer-set (group)
function cntLyrS(lyrs,c){
    if(!c){
        if(lyrs.typename!='LayerSet') return 0;
        c = 0;
    }
    var ls = lyrs.layers.length;
    var i = 0;
    while(i<ls){
        c++;
        if(lyrs.layers[i].typename=='LayerSet') c=cntLyrS(lyrs.layers[i],c);
        i++;
    }
    return c+1;
}

// make new layer below current or [LayerNum], optionally [ignoreGroups]
function mkLyrBelow(LyrN,noGr){
    var doc = app.activeDocument;
    if(!doc) return false;
    if(LyrN){
        selLyr(LyrN);
    }else{
        LyrN = curLyrN();
        if(!LyrN) return false;
    }
    var actv = doc.activeLayer;
    if(actv.isBackgroundLayer) actv.isBackgroundLayer=false;
    mkLyr();
    if(curLyrN()==LyrN) return true;
    if(!noGr){
        var lc = cntLyrS(actv);
        if(lc && lc<LyrN-1) LyrN -= lc;
    }
    return movLyr(LyrN-1);
}

即使它看起来相当麻烦和可怕 - 我怀疑它会表现得慢得多。作为奖励,它将在历史记录中创建最少量的操作(没有不必要的图层移动)+它将正确地与背景图层一起使用+它将适用于组(图层集):如果组被打开 - 它将创建其中的新图层,如果组关闭,它将在整个组结构下正确移动图层,包括所选组内的其他可能组。

使用它:mkLyrBelow();在选定的图层下创建新图层,或mkLyrBelow(LayerNumber);通过它的编号在另一个图层下创建图层,也可以选择添加2d参数来忽略组(它将会在群组中移动新图层即使已关闭):mkLyrBelow(LayerNumber,true);mkLyrBelow(0,1); ...

P.S。不要误解ActionRefs - 它们不是银弹,最后通常会有更多的便利,但是当你将ARef与原生API结合起来时,取得了最好的结果。只要相信我,我就像8年前编写了我的第一个PS脚本,所以我几乎尝试了所有东西=)

答案 2 :(得分:-2)

如果我理解你的问题,Photoshop已经有了这些快捷方式

  

Ctrl + Shift + N(创建新图层)

     

Ctrl +](向上移动图层)

     

Ctrl + [(将图层向下移动)