如何在已知名称的其他组图层中裁剪和导出特定的组图层?

时间:2019-05-31 20:23:32

标签: jsx photoshop-script

第一次在这里发布!如果此贴缺少信息或令人讨厌,我事先表示歉意。

所以,我有一堆层,结构有点像这样:

+ graphics (group, unique)
+ - + Figure_A (group, unique)
+ - + - + Figure_A_arm (group, unique)
+ - + - + - + Figure_A_arm_Variation1 (group, unique)
+ - + - + - + - + frame1_arm (group, not unique)
+ - + - + - + - + - + FigureGraphic (linked layer, not unique, has a mask)
+ - + - + - + - + frame2_arm (group, not unique)
+ - + - + - + - + - + FigureGraphic (linked layer, not unique, has a mask)
+ - + - + - + - + frame2_arm (group, not unique)
+ - + - + - + - + - + FigureGraphic (linked layer, not unique, has a mask)

(唯一/不唯一表示图层名称是否唯一)

我正在尝试获取组层次结构中最新的像素,并在自动导出之前裁剪文档。主要的问题是,即使不停地戳了两周,我还是不知道有很多功能。我在脚本中挖了很多代码片段,但结果变成一团糟,无法正常工作。 我要在尝试执行的操作中包含伪代码。理想情况下,我会在其中编写这些函数,但是在谷歌搜索了两个星期之后,我看不清其中的很多功能。 Photoshop脚本中的许多功能似乎相当模糊,我根本无法弄清楚它们……

我一直在通过从以下位置获取代码段来编写函数:

导出为PNG:Photoshop CS6 Export Nested Layers to PNG?

选择所有子层:http://www.joonas.me/posts/2018/01/30/select-child-layers-photoshop-script/

获取选定的图层ID:https://forums.adobe.com/thread/2256708

通过ID:https://forums.adobe.com/thread/2140075

选择图层

我一直在尝试,但是我发现很难实现它们来执行我需要的操作,有时我会遇到错误,或者变量变得“未定义”,从而引发错误。

// Here's some 'pseudocode' with how I'm trying to make it work
cropAndSave("Figure_A_arm_Variation1");
cropAndSave("Figure_A_arm_Variation2");
cropAndSave("Figure_A_arm_Variation3");
cropAndSave("Figure_A_leg_Variation1");
cropAndSave("Figure_A_leg_Variation2");
cropAndSave("Figure_A_leg_Variation3");
cropAndSave("Figure_B_arm_Variation1");
cropAndSave("Figure_B_arm_Variation2");
cropAndSave("Figure_B_arm_Variation3");
//etc

function cropAndSave(nameOfGroup)
{
    //nameOfGroup is the group layer we are looking for

    //Duplicate the document so we don't mess with the original
    var workingDoc = app.activeDocument.duplicate();

    // Path we want to export to
    var path="C:/test/"+nameOfGroup+"/";

    // Look up for this group layer in the document
    setActiveLayerSet(nameOfGroup);

    // Make a list (array?) with the ids of each layer set/group inside nameOfGroup
    // This shouldn't include anything inside each group, only the direct groups inside nameOfGroup
    var listOfLayers = getListOfChildrenObjects();

    // Loop the process for each sub-object
    for( var i = 0; i < listOfLayers.length ; i++ )
    {
        var name = getLayerNameById(listOfLayers.i); //I don't know if this is the correct way to ask for the i element of a list
        var bounds = []; //We'll be using this for the cropping
        if(groupName=="Figure_A_arm_Variation1") //Checking which set we're doing
        {
            if(name=="frame1_arm") bounds = [1px, 2px, 3px, 4px]; //just a test value
            else if(name=="frame2_arm") bounds = [5px, 6px, 7px, 8px]; //just a test value
            else if(name=="frame3_arm") bounds = [9px, 10px, 11px, 12px]; //just a test value
            else if(name=="frame1_leg") bounds = [13px, 14px, 15px, 16px]; //just a test value
            // and so on
        }
        else if(groupName=="Figure_B_arm_Variation2") //one of the many possible groups
        {
            if(name=="frame1_arm") bounds = [17px, 18px, 19px, 20px];
            //etc
        }
        // Duplicate this since we will be doing more drastic changes
        var secondaryDoc = workingDoc.duplicate();

        // Select the layer we're working with
        selectLayerByID(listOfLayers.i);

        // Do the cropping
        if(bounds.length > 2) secondaryDoc.crop(bounds); //Each bounds array has 4 elements, check if that's the case to make sure we haven't input any weird values, then crop
        else alert('No bounds set up for layer '+name+' in group '+groupName); //in this case it should be cancelled but I'm not sure how to stop the script from executing

        // Condense the group 'name', which is the one we're working with, into a single layer for easier management
        condenseGroup();

        // Remove all the layers that aren't the one we're working with
        deleteAllLayersAndGroupsExceptSelected();

        // Save as PNG
        var pngFile = new File(path+name);
        pngSaveOptions = new PNGSaveOptions();
        pngSaveOptions.embedColorProfile = true;
        pngSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
        pngSaveOptions.matte = MatteType.NONE; pngSaveOptions.quality = 1;
        activeDocument.saveAs(pngFile, pngSaveOptions, false, Extension.LOWERCASE);

        // Close this duplicate without saving the PSD
        secondaryDoc.close(SaveOptions.DONOTSAVECHANGES);
    }
    workingDoc.close(SaveOptions.DONOTSAVECHANGES); 
}

所以我要摆脱的是,在具有特定的组结构的同时,使其在层次结构中选择一个组,然后将文档裁剪为一组后,将每个子组的内容另存为PNG。尺寸,但我很难找到正确的方法和功能。

[编辑]请求的图像发​​布在这里:

这是Layer structure。每个“ Figure_ X _ bodypart _Variation Y ”中都有一组子组。我想通过将文档裁剪为特定的边界来处理这些子组中的每个子组,这些边界已编码到每个子组的脚本中。

I have the PSD structured like this,打开的文件夹有一个遮罩(这是用于显示哪些像素属于该图层的当前选择)。我希望脚本选择为该图层指定的矩形,例如this

之后,我希望脚本复制文档(以免与原始文档混淆),然后在脚本中为该组提供crop using the bounds。之后,脚本should remove all the other groups so only this one remains将其保存为PNG,然后关闭重复的文档,然后继续下一个子对象。

完成所有子对象后,继续每个“ Figure_ X _ bodypart _Variation Y ”类型组

1 个答案:

答案 0 :(得分:0)

输入:

enter image description here

输出:

enter image description here

var exportPath = "/C/test-export",
    bounds = {
        child1: [
            44,
            92,
            338,
            363
        ],
        child2: [
            263,
            62,
            536,
            315
        ],
        child3: [
            160,
            269,
            458,
            497
        ]
    };

cropAndExport("figureA");

function cropAndExport(groupName)
{
    var doc = activeDocument;

    var masterClone = cloneDoc(); // master clone of the document

    masterClone.activeLayer = masterClone.layers.getByName(groupName); // selecting a group by name
    var groupChildren = masterClone.activeLayer.layers; // getting children of the group

    for (var i = 0; i < groupChildren.length; i++)
    {
        masterClone.activeLayer = groupChildren[i];
        var clone = cloneDoc();
        mergeDown(); // merging the group
        toggleVisibility(); //hiding all the other groupChildren
        rectSelection(bounds[groupChildren[i].name]); //you can use ifs to load bounds you want here, like if (groupChildren[i].name == 'child1') rectSelection(boundChild1);
        cropToSelection()
        savePng24(groupName, groupChildren[i].name, exportPath)
        clone.close(SaveOptions.DONOTSAVECHANGES);
    };

    masterClone.close(SaveOptions.DONOTSAVECHANGES);

    /////////////////////////////////////////////////////////////////////////////////////
    // functions
    /////////////////////////////////////////////////////////////////////////////////////

    function savePng24(nameX, nameY, exportFolder)
    {
        var pngOpts = new ExportOptionsSaveForWeb;
        pngOpts.format = SaveDocumentType.PNG
        pngOpts.PNG8 = false;
        pngOpts.transparency = true;
        activeDocument.exportDocument(new File(exportFolder + "/" + nameX + "_" + nameY + ".png"), ExportType.SAVEFORWEB, pngOpts);
    }; // end of savePng24()

    function cloneDoc()
    {
        var desc2 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Frst'));
        desc2.putReference(cTID('null'), ref1);
        desc2.putString(cTID('Nm  '), 'clone');
        executeAction(cTID('Dplc'), desc2, DialogModes.NO);
        return activeDocument;
    }; // end of cloneDoc()

    function mergeDown()
    {
        var desc11 = new ActionDescriptor();
        executeAction(cTID('Mrg2'), desc11, DialogModes.NO);
    }; // end of mergeDown()

    function toggleVisibility()
    {
        var desc102 = new ActionDescriptor();
        var list5 = new ActionList();
        var ref18 = new ActionReference();
        ref18.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        list5.putReference(ref18);
        desc102.putList(cTID('null'), list5);
        desc102.putBoolean(cTID('TglO'), true);
        executeAction(cTID('Shw '), desc102, DialogModes.NO);
    }; // end of toggleVisibility()

    function rectSelection(data)
    {
        var desc25 = new ActionDescriptor();
        var ref1 = new ActionReference();
        ref1.putProperty(cTID('Chnl'), cTID('fsel'));
        desc25.putReference(cTID('null'), ref1);
        var desc26 = new ActionDescriptor();
        desc26.putUnitDouble(cTID('Left'), cTID('#Pxl'), data[0]);
        desc26.putUnitDouble(cTID('Top '), cTID('#Pxl'), data[1]);
        desc26.putUnitDouble(cTID('Rght'), cTID('#Pxl'), data[2]);
        desc26.putUnitDouble(cTID('Btom'), cTID('#Pxl'), data[3]);
        desc25.putObject(cTID('T   '), cTID('Rctn'), desc26);
        executeAction(cTID('setd'), desc25, DialogModes.NO);
    }; // end of rectSelection()

    function cropToSelection()
    {
        var desc33 = new ActionDescriptor();
        desc33.putBoolean(cTID('Dlt '), true);
        executeAction(cTID('Crop'), desc33, DialogModes.NO);
    }; // end of cropToSelection()


    function cTID(s)
    {
        return app.charIDToTypeID(s);
    };

    function sTID(s)
    {
        return app.stringIDToTypeID(s);
    };


}