Как обрезать и экспортировать определенные групповые слои внутри других групповых слоев с известным именем? - PullRequest
0 голосов
/ 31 мая 2019

первый раз здесь! Заранее извиняюсь, если в этом сообщении отсутствует информация, или если это бельмо на глазу!

Итак, у меня есть несколько слоев, структурированных вроде этого в качестве примера:

+ 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 Экспорт вложенных слоев в PNG?

Выбрать все дочерние слои: http://www.joonas.me/posts/2018/01/30/select-child-layers-photoshop-script/

Получить идентификаторы выбранного слоя: 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 после обрезки документа в наборе. размеров, но у меня возникают трудности с поиском правильного способа и функций для этого.

[Редактировать] Запрошенные изображения размещены здесь:

Это структура слоя . Каждый «Figure_ X _ bodypart _Variation Y » содержит набор подгрупп. Я хочу обработать каждую из этих подгрупп, обрезав документ до определенных границ, которые закодированы в сценарии для каждой из них.

У меня PSD структурирован следующим образом , у открытой папки есть маска (которая является текущим выбором, чтобы показать, какие пиксели принадлежат этому слою). Я хочу, чтобы скрипт выбрал прямоугольник, указанный для этого слоя, например this .

После этого я хочу, чтобы скрипт дублировал документ (чтобы он не мешал оригиналу), а затем обрезал с использованием границ , которые я дал в сценарии для этой группы. После этого сценарий должен удалить все остальные группы, чтобы осталась только эта , и сохранить его как PNG, затем закрыть дублированный документ и перейти к следующему подобъекту.

После того, как все подобъекты выполнены, продолжайте с каждой группой типа "Figure_ X _ bodypart _Variation Y "

1 Ответ

0 голосов
/ 02 июня 2019

Вход:

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);
    };


}
...