前面我们所处理的图层位于图层的“根目录”下,可以直接通过docRef. artLayers. getByName获取。
但是更多的时候,PSD文件中有许多LayerSet,要处理的图层在LayerSet中,甚至包含几层嵌套,不能直接以上面的方法获取,如下图“这还是小黄人”的文本图层在一个多层嵌套中。(要创建LayerSet点击箭头所指图标即可,创建二级LayerSet需先点击一级LayerSet。 创建LayerSet后可把图层拖到文件夹中)
- 递归查找
像这种情况,要获取到“这是小黄人”和“这还是小黄人”的图层就不能直接用artLayers. getByName方法了,会提示错误。这种情况,要通过递归查找来找到对应图层。以修改文本为例,我们查找并修改“这还是小黄人”的文本。我们实现一个通过递归查找来修改指定文本图层的函数。
//参数分别是文件,要查找的图层名字,要替换的名字
function changeTextLayerContent(doc, layerName, newTextString) {
//分析当前layers.length,这个layers可以是Layer也可以是LayerSet,逻辑上是当做LayerSet处理
for (var i = 0, max = layers.length; i < max; i++) {
//取LayerSet的每一个Layer/LayerSet
var layerRef = doc.layers[i];
if (layerRef.typename === "ArtLayer") {
//找到就修改
if (layerRef.name === layerName && layerRef.kind === LayerKind.TEXT) {
layerRef.textItem.contents = newTextString;
}
} else {
//没找到就继续递归查找
changeTextLayerContent(layerRef, layerName, newTextString);
}
}
}
我们调用这个函数
var fileRef = new File('E:/小黄人.psd');
var docRef = app.open(fileRef);
changeTextLayerContent(docRef, '这还是小黄人', '成功修改');
- 顺序查找
递归查找的优点是使用方便,不管图层处在什么位置都能够找到,缺点是速度慢,如果图层结构比较复杂,程序运行的时间会不忍直视。在知道图层结构关系的情况下,我们可以按结构关系顺序查找图层。
var MyLayerSet = docRef.layerSets.getByName( 'LayerSet' );
alert(MyLayerSet.name);
var MyLayerSubSet = MyLayerSet.layerSets.getByName( 'LayerSubSet' );
alert(MyLayerSubSet.name);
var MyTextlayer = MyLayerSubSet.artLayers.getByName( '这也是小黄人' );
alert(MyTextlayer.name);
MyTextlayer.textItem.contents = '成功修改';
注意,查找图层集的时候用的是layerSets.getByName,查找图层的时候用的是artLayers.getByName,这是需要区分的,否则程序会运行错误,这段代码的运行效果和递归查找的效果相同。
- 直接获取
既然我们都知道图层结构了,其实根本就不用查找,可以直接根据图层结构关系索引图层,从递归函数里我们可以看到,LayerSet和Layer的数据结构在操作上是可以同等看待的(但注意查找的时候是有区别),我们可以直接索引。
var MyTextlayer1 = docRef.layers[0].layers[0];
MyTextlayer1.textItem.contents = '成功修改一';
var MyTextlayer2 = docRef.layers[0].layers[1].layers[0];
MyTextlayer2.textItem.contents = '成功修改二';
从上述代码我们可以看到,Layer和LayerSet按索引的获取方式是相同的,docRef.layers[0].layers[0]是一个Layer,而docRef.layers[0].layers[1]则是一个LayerSet。最终修改效果如下: